| SystemVerilog | |
|---|---|
| Paradigms | Structured (design) Object-oriented (verification) |
| Designed by | Synopsys, laterIEEE |
| First appeared | 2002; 24 years ago (2002) |
| Stable release | IEEE 1800-2023 / December 16, 2023; 2 years ago (2023-12-16) |
| Typing discipline | Static,weak |
| Filename extensions | .sv,.svh |
| Influenced by | |
| Verilog,VHDL,C++ (design) OpenVera,Java (verification) | |
SystemVerilog,standardized asIEEE 1800 by theInstitute of Electrical and Electronics Engineers (IEEE), is ahardware description andhardware verification language commonly used to model,design,simulate,test andimplement electronic systems in thesemiconductor andelectronic design industry. SystemVerilog is an extension ofVerilog.
SystemVerilog started with the donation of theSuperlog language toAccellera in 2002 by the startup company Co-Design Automation.[1] The bulk of the verification functionality is based on the OpenVera language donated bySynopsys. In 2005, SystemVerilog was adopted asIEEE Standard 1800-2005.[2] In 2009, the standard was merged with the base Verilog (IEEE 1364-2005) standard, creating IEEE Standard 1800-2009.
The SystemVerilog standard was subsequently updated in 2012,[3] 2017,[4] and most recently in December 2023.[5]
The feature-set of SystemVerilog can be divided into two distinct roles:
The remainder of this article discusses the features of SystemVerilog not present inVerilog-2005.
There are two types of data lifetime specified in SystemVerilog:static andautomatic. Automatic variables are created the moment program execution comes to the scope of the variable. Static variables are created at the start of the program's execution and keep the same value during the entire program's lifespan, unless assigned a new value during execution.
Any variable that is declared inside a task or function without specifying type will be considered automatic. To specify that a variable is static place the "static"keyword in the declaration before the type, e.g., "static int x;". The "automatic" keyword is used in the same way.
Enhanced variable types add new capability to Verilog's "reg" type:
logic[31:0]my_var;
Verilog-1995 and -2001 limit reg variables to behavioral statements such asRTL code. SystemVerilog extends the reg type so it can be driven by a single driver such as gate or module. SystemVerilog names this type "logic" to remind users that it has this extra capability and is not a hardware register. The names "logic" and "reg" are interchangeable. A signal with more than one driver (such as atri-state buffer forgeneral-purpose input/output) needs to be declared a net type such as "wire" so SystemVerilog can resolve the final value.
Multidimensionalpacked arrays unify and extend Verilog's notion of "registers" and "memories":
logic[1:0][2:0]my_pack[32];
Classical Verilog permitted only one dimension to be declared to the left of the variable name. SystemVerilog permits any number of such "packed" dimensions. A variable of packed array type maps 1:1 onto an integer arithmetic quantity. In the example above, each element ofmy_pack may be used in expressions as a six-bit integer. The dimensions to the right of the name (32 in this case) are referred to as "unpacked" dimensions. As inVerilog-2001, any number of unpacked dimensions is permitted.
Enumerated data types (enums) allow numeric quantities to be assigned meaningful names. Variables declared to be of enumerated type cannot be assigned to variables of a different enumerated type withoutcasting. This is not true of parameters, which were the preferred implementation technique for enumerated quantities in Verilog-2005:
typedefenumlogic[2:0]{RED,GREEN,BLUE,CYAN,MAGENTA,YELLOW}color_t;color_tmy_color=GREEN;initial$display("The color is %s",my_color.name());
As shown above, the designer can specify an underlying arithmetic type (logic [2:0] in this case) which is used to represent the enumeration value. The meta-values X and Z can be used here, possibly to represent illegal states. The built-in functionname() returns an ASCII string for the current enumerated value, which is useful in validation and testing.
New integer types: SystemVerilog definesbyte,shortint,int andlongint as two-state signed integral types having 8, 16, 32, and 64 bits respectively. Abit type is a variable-width two-state type that works much likelogic. Two-state types lack theX andZ metavalues of classical Verilog; working with these types may result in faster simulation.
Structures andunions work much like they do in theC language. SystemVerilog enhancements include thepacked attribute and thetagged attribute. Thetagged attribute allows runtime tracking of which member(s) of a union are currently in use. Thepacked attribute causes the structure or union to be mapped 1:1 onto a packed array of bits. The contents ofstruct data types occupy a continuous block of memory with no gaps, similar tobit fields in C and C++:
typedefstructpacked{bit[10:0]expo;bitsign;bit[51:0]mant;}FP;FPzero=64'b0;
As shown in this example, SystemVerilog also supportstypedefs, as in C and C++.
SystemVerilog introduces three new procedural blocks intended to modelhardware:always_comb (to modelcombinational logic),always_ff (forflip-flops), andalways_latch (forlatches). Whereas Verilog used a single, general-purposealways block to model different types of hardware structures, each of SystemVerilog's new blocks is intended to model a specific type of hardware, by imposing semantic restrictions to ensure that hardware described by the blocks matches the intended usage of the model. An HDL compiler or verification program can take extra steps to ensure that only the intended type of behavior occurs.
Analways_comb block modelscombinational logic. The simulator infers the sensitivity list to be all variables from the contained statements:
always_combbegintmp=b*b-5'h4*a*c;no_root=(tmp<0);end
Analways_latch block modelslevel-sensitive latches. Again, the sensitivity list is inferred from the code:
always_latchif(en)q<=d;
Analways_ff block modelssynchronous logic (especiallyedge-sensitivesequential logic):
always_ff@(posedgeclk)count<=count+4'd1;
Electronic design automation (EDA) tools can verify the design's intent by checking that the hardware model does not violate any block usage semantics. For example, the new blocks restrict assignment to a variable by allowing only one source, whereas Verilog'salways block permitted assignment from multiple procedural sources.
When performing arithmetic operations with static numeric literals in RTL code, it is important to explicitly specify the bit-width of constants to avoid unintended truncation, linting violations or synthesis issues. This is particularly critical in combinational and sequential logic blocks. When operands lack explicit bit specifications, simulators and synthesis tools may infer widths based on context or default to implementation-specific sizes, potentially causing data loss or unexpected behavior during simulation or hardware implementation.
For small designs, the Verilogport compactly describes a module's connectivity with the surrounding environment. But major blocks within a large design hierarchy typically possess port counts in the thousands. SystemVerilog introduces the concept ofinterfaces to both reduce the redundancy ofport-name declarations between connected modules, as well as group andabstract related signals into a user-declared bundle. An additional concept ismodport, which shows the direction of logic connections.
Example:
interfaceintf;logica;logicb;modportin(inputa,outputb);modportout(inputb,outputa);endinterfacemoduletop;intfi();u_am1(.i1(i.in));u_bm2(.i2(i.out));endmodulemoduleu_a(intf.ini1);endmodulemoduleu_b(intf.outi2);endmodule
The following verification features are typically not synthesizable, meaning they cannot be implemented in hardware based on HDL code. Instead, they assist in the creation of extensible, flexibletest benches.
Thestring data type represents a variable-length textstring. For example:
strings1="Hello";strings2="world";stringp=".?!";strings3={s1,", ",s2,p[2]};// string concatenation$display("[%d] %s",s3.len(),s3);// simulation will print: "[13] Hello, world!"
In addition to the static array used in design, SystemVerilog offersdynamic arrays,associative arrays andqueues:
intcmdline_elements;// # elements for dynamic arrayintda[];// dynamic arrayintai[int];// associative array, indexed by intintas[string];// associative array, indexed by stringintqa[$];// queue, indexed as an array, or by built-in methodsinitialbegincmdline_elements=16;da=new[cmdline_elements];// Allocate array with 16 elementsend
A dynamic array works much like an unpacked array, but offers the advantage of beingdynamically allocated atruntime (as shown above.) Whereas a packed array's size must be known at compile time (from a constant or expression of constants), the dynamic array size can be initialized from another runtime variable, allowing the array to be sized and resize arbitrarily as needed.
An associative array can be thought of as abinary search tree with auser-specifiedkey type and data type. The key implies anordering; the elements of an associative array can be read out in lexicographic order. Finally, a queue provides much of the functionality of theC++ STLdeque type: elements can be added and removed from either end efficiently. These primitives allow the creation of complex data structures required forscoreboarding a large design.
SystemVerilog provides anobject-oriented programming model.
In SystemVerilog, classes support asingle-inheritance model, but may implement functionality similar to multiple-inheritance through the use of so-called "interface classes" (identical in concept to theinterface feature of Java). Classescan be parameterized by type, providing the basic function ofC++ templates. However,template specialization andfunction templates are not supported.
SystemVerilog'spolymorphism features are similar to those of C++: the programmer may specifically write avirtual function to have a derived class gain control of the function. Seevirtual function for further information.
Encapsulation anddata hiding is accomplished using thelocal andprotected keywords, which must be applied to any item that is to be hidden. By default, all class properties arepublic.
Class instances are dynamically created with thenew keyword. Aconstructor denoted byfunction new can be defined. SystemVerilog has automaticgarbage collection, so there is no language facility to explicitly destroy instances created by thenew operator.
Example:
virtualclassMemory;virtualfunctionbit[31:0]read(bit[31:0]addr);endfunctionvirtualfunctionvoidwrite(bit[31:0]addr,bit[31:0]data);endfunctionendclassclassSRAM#(parameterAWIDTH=10)extendsMemory;bit[31:0]mem[1<<AWIDTH];virtualfunctionbit[31:0]read(bit[31:0]addr);returnmem[addr];endfunctionvirtualfunctionvoidwrite(bit[31:0]addr,bit[31:0]data);mem[addr]=data;endfunctionendclass
Integer quantities, defined either in a class definition or as stand-alone variables in some lexical scope, can beassigned random values based on a set of constraints. This feature is useful for creatingrandomized scenarios for verification.
Within class definitions, therand andrandc modifiers signal variables that are to undergo randomization.randc specifiespermutation-based randomization, where a variable will take on all possible values once before any value is repeated. Variables without modifiers are not randomized.
classeth_frame;randbit[47:0]dest;randbit[47:0]src;randbit[15:0]f_type;randbytepayload[];bit[31:0]fcs;randbit[31:0]fcs_corrupt;constraintbasic{payload.sizeinside{[46:1500]};}constraintgood_fr{fcs_corrupt==0;}endclass
In this example, thefcs field is not randomized; in practice it will be computed with a CRC generator, and thefcs_corrupt field used to corrupt it to inject FCS errors. The two constraints shown are applicable to conformingEthernet frames. Constraints may be selectively enabled; this feature would be required in the example above to generate corrupt frames. Constraints may be arbitrarily complex, involving interrelationships among variables, implications, and iteration. The SystemVerilogconstraint solver is required to find a solution if one exists, but makes no guarantees as to the time it will require to do so as this is in general anNP-hard problem (boolean satisfiability).
In each SystemVerilog class there are 3 predefined methods for randomization: pre_randomize, randomize and post_randomize. The randomize method is called by the user for randomization of the class variables. The pre_randomize method is called by the randomize method before the randomization and the post_randomize method is called by the randomize method after randomization.
classeth_frame;randbit[47:0]dest;randbit[47:0]src;randbit[15:0]f_type;randbytepayload[];bit[31:0]fcs;randbitcorrupted_frame;constraintbasic{payload.sizeinside{[46:1500]};}functionvoidpost_randomize()this.calculate_fcs();// update the fcs field according to the randomized frameif(corrupted_frame)// if this frame should be corruptedthis.corrupt_fcs();// corrupt the fcsendfunctionendclass
The constraint_mode() and the random_mode() methods are used to control the randomization. constraint_mode() is used to turn a specific constraint on and off and the random_mode is used to turn a randomization of a specific variable on or off. The below code describes and procedurally tests anEthernet frame:
classeth_frame;randbit[47:0]dest;randbit[47:0]src;randbit[15:0]f_type;randbytepayload[];bit[31:0]fcs;randbitcorrupted_frame;constraintbasic{payload.sizeinside{[46:1500]};}constraintone_src_cst{src==48'h1f00}constraintdist_to_fcs{fcsdist{0:/30,[1:2500]:/50};// 30, and 50 are the weights (30/80 or 50/80, in this example)}endclass...eth_framemy_frame;my_frame.one_src_cst.constraint_mode(0);// the constraint one_src_cst will not be taken into accountmy_frame.f_type.random_mode(0);// the f_type variable will not be randomized for this frame instance.my_frame.randomize();
Assertions are useful for verifying properties of a design that manifest themselves after a specific condition or state is reached. SystemVerilog has its own assertion specification language, similar toProperty Specification Language. The subset of SystemVerilog language constructs that serves assertion is commonly called SystemVerilog Assertion or SVA.[6]
SystemVerilog assertions are built fromsequences andproperties. Properties are a superset of sequences; any sequence may be used as if it were a property, although this is not typically useful.
Sequences consist ofboolean expressions augmented withtemporal operators. The simplest temporal operator is the## operator which performs a concatenation:[clarification needed]
sequenceS1;@(posedgeclk)req##1gnt;endsequence
This sequence matches if thegnt signal goes high one clock cycle afterreq goes high. Note that all sequence operations are synchronous to a clock.
Other sequential operators include repetition operators, as well as various conjunctions. These operators allow the designer to express complex relationships among design components.
An assertion works by continually attempting to evaluate a sequence or property. An assertion fails if the property fails. The sequence above will fail wheneverreq is low. To accurately express the requirement thatgnt followreq a property is required:
propertyreq_gnt;@(posedgeclk)req|=>gnt;endpropertyassert_req_gnt:assertproperty(req_gnt)else$error("req not followed by gnt.");
This example shows animplication operator|=>. The clause to the left of the implication is called theantecedent and the clause to the right is called theconsequent.Evaluation of an implication starts through repeated attempts to evaluate the antecedent.When the antecedent succeeds, the consequent is attempted, and the success of the assertion depends on the success of the consequent. In this example, the consequent won't be attempted untilreq goes high, after which the property will fail ifgnt is not high on the following clock.
In addition to assertions, SystemVerilog supportsassumptions and coverage of properties. An assumption establishes a condition that aformal logicproving toolmust assume to be true. An assertion specifies a property that must be proven true. Insimulation, both assertions and assumptions are verified against test stimuli. Property coverage allows the verification engineer to verify that assertions are accurately monitoring the design.[vague]
Coverage as applied to hardware verification languages refers to the collection of statistics based on sampling events within the simulation. Coverage is used to determine when thedevice under test (DUT) has been exposed to a sufficient variety of stimuli that there is a high confidence that the DUT is functioning correctly. Note that this differs fromcode coverage which instruments the design code to ensure that all lines of code in the design have been executed. Functional coverage ensures that all desiredcorner andedge cases in thedesign space have beenexplored.
A SystemVerilog coverage group creates a database of "bins" that store ahistogram of values of an associated variable. Cross-coverage can also be defined, which creates a histogram representing theCartesian product of multiple variables.
Asampling event controls when a sample is taken. Thesampling event can be a Verilog event, the entry or exit of a block of code, or a call to thesample method of the coverage group. Care is required to ensure that data are sampled only when meaningful.
For example:
classeth_frame;// Definitions as abovecovergroupcov;coverpointdest{binsbcast[1]={48'hFFFFFFFFFFFF};binsucast[1]=default;}coverpointf_type{binslength[16]={[0:1535]};binstyped[16]={[1536:32767]};binsother[1]=default;}psize:coverpointpayload.size{binssize[]={46,[47:63],64,[65:511],[512:1023],[1024:1499],1500};}sz_x_t:crossf_type,psize;endgroupendclass
In this example, the verification engineer is interested in the distribution of broadcast and unicast frames, the size/f_type field and the payload size. The ranges in the payload size coverpoint reflect the interesting corner cases, including minimum and maximum size frames.
A complex test environment consists of reusable verification components that must communicate with one another. Verilog's 'event' primitive allowed different blocks of procedural statements to trigger each other, but enforcing threadsynchronization was up to the programmer's (clever) usage. SystemVerilog offers twoprimitives specifically for interthread synchronization:mailbox andsemaphore. The mailbox is modeled as aFIFO message queue. Optionally, the FIFO can betype-parameterized so thatonly objects of the specified type may be passed through it. Typically, objects areclass instances representingtransactions: elementary operations (for example, sending a frame) that are executed by the verification components. The semaphore is modeled as acounting semaphore.
In addition to the new features above, SystemVerilog enhances the usability of Verilog's existing language features. The following are some of these enhancements:
x++,++x,x--,--x) are supported in SystemVerilog, as are othercompound assignment operators (x += a,x -= a,x *= a,x /= a,x %= a,x <<= a,x >>= a,x &= a,x ^= a,x |= a) as inC and descendants.Besides this, SystemVerilog allows convenientinterface to foreign languages (like C/C++), bySystemVerilog DPI (Direct Programming Interface).
In the design verification role, SystemVerilog is widely used in the chip-design industry. The three largest EDA vendors (Cadence Design Systems,Mentor Graphics,Synopsys) have incorporated SystemVerilog into their mixed-languageHDL simulators. Although no simulator can yet claim support for the entire SystemVerilog Language Reference Manual, making testbenchinteroperability a challenge, efforts to promote cross-vendor compatibility are underway.[when?] In 2008, Cadence and Mentor released the Open Verification Methodology, an open-source class-library and usage-framework to facilitate the development of re-usable testbenches and canned verification-IP. Synopsys, which had been the first to publish a SystemVerilog class-library (VMM), subsequently responded by opening its proprietary VMM to the general public. Many third-party providers have announced or already released SystemVerilog verification IP.
In thedesign synthesis role (transformation of a hardware-design description into a gate-netlist), SystemVerilog adoption has been slow. Many design teams use design flows which involve multiple tools from different vendors. Most design teams cannot migrate to SystemVerilog RTL-design until their entire front-end tool suite (linters,formal verification andautomated test structure generators) support a common language subset.[needs update?]