You are on page 1of 31

SystemVerilog – Lecture 1

1

From Verilog to SystemVerilog
• SystemVerilog is the third generation of the Verilog language standard: 1st generation standard: Verilog-1995 2nd generation standard: Verilog-2001. 3rd generation standard: SystemVerilog. • SystemVerilog is a significant and important extension of Verilog-2001, and it includes many features which are useful for high-level modeling and verification of large and complex designs.

2

Using SystemVerilog With VCS
• By convention, SystemVerilog files use the extension .sv

For example:
design1.sv, tbdesign1.sv

• To compile SystemVerilog code with VCS, use the –sverilog flag when compiling.

For example:
vcs –sverilog design1.sv tbdesign1.sv ./simv

3

Built-in Data Types
• We'll start with some of the simpler

elements of the language and give some design examples before moving on to the more complex features that are available. • 4-state data types: (0, 1, x or z values)
reg, logic, integer, wire, wor, wand (logic is identical to reg)

• 2-state data types: (only 0 or 1 values)
bit, byte, shortint, int, longint
4

Unsigned and Signed Data Types
• Keywords signed and unsigned can be

used to override the default numeric properties: • logic is unsigned by default:
logic [7:0] a; // a is unsigned logic signed [7:0] b; // b is signed

• int is 32-bit signed by default:
int c; // c is 32-bit signed int unsigned d; // 32-bit unsigned
5

Assigning the Same Value to all Bits
• The common value 0, 1, x or z can be

assigned to all bit positions of a vector with a new and simple syntax:
my_bus my_bus my_bus my_bus = = = = '0; '1; 'x; 'z; // // // // fills fills fills fills with with with with all all all all 0 1 x z

6

. d). adding the sign-extended values and then returning the 10 most significant bits (MSBs) of the sum as the output of the module. (Note: This is called "Step 1a" of a larger example which will be considered later. endmodule 7 Example: 10-bit Truncated Adder • • Design a ripple-carry adder module for adding two 10-bit signed numbers by first sign-extending each operand to 11 bits. note that the truncation may introduce a small error compared to the full-precision result. . input logic c. Also. p[9:0] q[9:0] 10-bit truncated adder r[10:1] 8 . b..) Note that you must correctly scale the power-of-two weights of these output bits when interpreting the numerical value that is produced at the output.Module Inputs and Outputs • We can specify the direction and the type of the signals going in and out of a module directly in the module statement itself: module simple (output logic a.

ha0(p[0]. cin. assign s = a^b. r[4]. carry[1]). carry[7]. assign cout = a&b. carry[3]). carry[9]. fa4(p[4]. carry[1]. output logic [10:1] r). output logic s.SystemVerilog Code– Part 1 of 1 // half adder module half_adder(input logic a. carry[9]). // 10-bit truncated ripple-carry adder module RCA10(input logic [9:0] p. carry[3]. wire wire lsb_sum. [9:0] carry. b. endmodule // full addder module full_adder(input logic a. q[5]. half_adder full_adder full_adder full_adder full_adder full_adder full_adder full_adder full_adder full_adder full_adder endmodule 10 . carry[2]. lsb_sum. r[2]. fa5(p[5]. r[5]. q[9]. r[1]. q[0]. cout). b. r[3]. fa8(p[8]. endmodule 9 SystemVerilog Code – cont. fa6(p[6]. carry[5]). carry[8]). carry[0]. fa2(p[2]. q[6]. q[4]. q[8]. carry[2]). r[7]. carry[4]). output logic s. carry[0]). assign cout = (a&b) | (b&cin) | (a&cin). fa9(p[9]. assign s = a^b^cin. carry[7]). q. carry[6]). q[9]. r[10]. r[8]. q[3]. q[2]. fa7(p[7]. r[9]. carry[8]. cout). carry[4]. carry[6]. fa1(p[1]. msb_carry. r[6]. fa3(p[3]. carry[5]. q[7]. msb_carry). q[1]. fa10(p[9].

// loop through all possible cases and record the results for (i = 0. // exhaustive checking of all 1024*1024 possible cases logic signed [9:0] x. y.1. if (sval == check) num_correct = num_correct + 1. sval. x. // adjust check value for truncation if (((check % 2) == 1) || ((check % 2) == -1)) check = check . but is useful for debugging // $display($time. num_wrong = %d". integer sval. on next page) • Construct a testbench to perform exhaustive testing of this module to prove that your design code is correct. num_correct. y. module tbstep1. integer num_wrong. end endmodule 12 . // following line is commented out. check = x + y. for (j = 0. Note that the check value calculated in the testbench should correctly model the truncation and scaling process used in the design. else num_wrong = num_wrong + 1. end end // print the final counter values $display("num_correct = %d. // testbench for adder of Step 1a. integer i. num_wrong). integer check. j.Testbench (cont. logic signed [9:0] s. j = j + 1) begin y = j. 11 // exhaustive simulation of all possible cases initial begin // initialize the counter variables num_correct = 0. num_wrong = 0. i < 1024. // compute and check the sum #10 sval = s*2. wrong // instantiate the adder RCA10 adder_instance(x. integer num_correct. correct counter to keep track of num. " %d + %d = %d (%d)". check). i = i + 1) begin x = i. // // // // // // // 10-bit signed inputs 10-bit sum output of the adder scaled value of the sum value used to check correctness loop variables counter to keep track of num. j < 1024. y. s).

Then. then a portion of the output looks as follows (notice the truncation): 102000 102010 102020 102030 102040 102050 102060 102070 102080 102090 9 9 9 9 9 9 9 9 9 9 + + + + + + + + + + -41 -40 -39 -38 -37 -36 -35 -34 -33 -32 = = = = = = = = = = -32 -32 -30 -30 -28 -28 -26 -26 -24 -24 ( ( ( ( ( ( ( ( ( ( -32) -32) -30) -30) -28) -28) -26) -26) -24) -24) 13 Carry Look-Ahead (CLA) Adders • Given two multi-bit operands A and B. Psum i = A i ⊕ B i • Assume that the carry into bit position i is Ci. Si. Ci+1. C i +1 = G i + Pi C i • A CLA adder uses the fact that these functions can be computed at all bit positions in parallel. and carry into the next higher bit position. Gi (generate) and Psumi (partial sum) at each bit position as follows: (Note that some references define propagate using the exclusive OR function. C1 = G 0 + P0 C 0 C 2 = G 1 + P1C1 = G 1 + P1 ( G 0 + P0 C 0 ) = G 1 + P1G 0 + P1P0 C 0 C 3 = G 2 + P2 C 2 = G 2 + P2 (G 1 + P1G 0 + P1P0 C 0 ) = G 2 + P2 G 1 + P2 P1G 0 + P2 P1 P0 C 0 C 4 = G 3 + P3C 3 = G 3 + P3 ( G 2 + P2 G 1 + P2 P1G 0 + P2 P1P0 C 0 ) = G 3 + P3G 2 + P3 P2 G 1 + P3 P2 P1G 0 + P3 P2 P1P0 C 0 14 . and this information can be used to speed up the carry (and hence the sum) computations.) Pi = A i + B i . are given by: S i = Psum i ⊕ C i . G i = A iB i . the sum at bit position i. we define the functions Pi (propagate).Testbench Results • The results from compiling and running the design and testbench are: num_correct = 1048576. num_wrong = 0 • If the debug statement is not commented out.

• Given the definitions of these group generate and propagate functions. they become impractical due to the the large number of terms involved and large fan-in gates that would be required. P3:0 = P3 P2 P1 P0 • Using these functions. While the previous set of substitutions could be continued to higher-order carries.e. we can define group generate and propagate functions for other. blocks) by forming block generate and propagate functions. we can define the group generate and propagate functions as: • G 3:0 = G 3 + P3 G 2 + P3 P2 G 1 + P3 P2 P1G 0 . • The previous equations determine the first four carries in parallel. which allows us to get block carries. For example.Carry Look-Ahead (CLA) Adders – Cont.. the equation for C4 can be written as follows: C 4 = G 3:0 + P3:0 C 0 • Similarly. nonoverlapping 4-bit groups: G i + 3:i = G i + 3 + Pi + 3 G i + 2 + Pi + 3 Pi + 2 G i +1 + Pi + 3 Pi + 2 Pi +1G i Pi + 3:i = Pi + 3 Pi + 2 Pi +1 Pi 15 Carry Look-Ahead (CLA) Adders – Cont. we can create the following group carries: C8 = G 7:4 + P7:4 C 4 = G 7:4 + P7:4 (G 3:0 + P3:0 C 0 ) = G 7:4 + P7:4 G 3:0 + P7:4 P3:0 C 0 C12 = G 11:8 + P11:8 C 8 = G 11:8 + P11:8 (G 7:4 + P7:4 G 3:0 + P7:4 P3:0 C 0 ) = G 11:8 + P11:8 G 7:4 + P11:8 P7:4 G 3:0 + P11:8 P7:4 P3:0 C 0 C16 = G 15:12 + P15:12 C12 = G 15:12 + P15:12 (G 11:8 + P11:8 G 7:4 + P11:8 P7:4 G 3:0 + P11:8 P7:4 P3:0 C 0 ) = G 15:12 + P15:12 G 11:8 + P15:12 P11:8 G 7:4 + P15:12 P11:8 P7:4 G 3:0 + P15:12 P11:8 P7:4 P3:0 C 0 • This can be extended to another level of hierarchy (i. blocks and sections. For example: G 15:0 = G 15:12 + P15:12 G 11:8 + P15:12 P11:8 G 7:4 + P15:12 P11:8 P7:4 G 3:0 P15:0 = P15:12 P11:8 P7:4 P3:0 ⇒ C 16 = G 15:0 + P15:0 C 0 16 . One alternative is to construct a hierarchical structure consisting of groups.

a series of o operators can be evaluated in any order).. Kogge-Stone (KS) Architecture • The n-bit KS design achieves the minimum logical depth of log2n levels. “A Family of Adders. Also. 21.e. G i:m + Pi:m G m −1. j ) = ( Pi: j . 2001. pp. It combines values at spans of distance 20.” 15th IEEE Symposium on Computer Arithmetic. G m −1. G i:m ) o ( Pm −1: j . j ) = ( Pi:m Pm −1: j . note that: Pi:i = Pi and Gi:i = Gi 17 • Simon Knowles. as illustrated on the following pages. by definition. where i > m > j: Pi: j = (Pi Pi −1 L Pm )(Pm −1Pm−2 L Pj ) = Pi:m Pm−1: j Gi: j = (Gi + Pi Gi −1 + Pi Pi −1Gi −2 +L+ Pi Pi −1 L Pm+1Gm ) + (Pi Pi −1 L Pm )Gm −1: j = Gi:m + Pi:mGm −1: j • Define an operator “o” which implements the recursive relations for Pi:j and Gi:j.Parallel Prefix Adders • Parallel prefix adders make use of recursive relations between group propagate and generate functions. … . 2n-1. This provides a great deal of flexibility in devising various parallel prefix adder architectures. 22. 277-284. The 8-bit KS design is: 18 .: ( Pi:m . m and j.e. i. G i: j ) • This operator is associative (i. Consider 3 bit positions i.

b[5]). g2. or(p[6]. b[6]). or(p[1]. b[7]). g1. a[6]. c6. c1. and(g[6]. a[1]. a[5]. b[7]). a[3]. b[2]). b[3]). a[5]. c2. b[3]). output bit p3. and(g[0]. b[2]). c3. a[1]. a[4]. xor(psum[7]. or(p[7]. b[3]). a[7]. 19 SystemVerilog Code for Kogge-Stone Adder – Part 2 of 4 // form the propagate. b[1]). a[6]. and(g[5]. and(g[3]. psum. a[6]. and(g[7]. xor(psum[3]. a[0]. xor(psum[1]. c5. b[0]). a[0]. [7:0] p.SystemVerilog Code for Kogge-Stone Adder – Part 1 of 4 module opo(input bit p1. c4. b[7]). xor(psum[6]. b[5]). b[0]). or(p[4]. and(g[2]. g3). a[2]. a[3]. p2. or(p[2]. bit c8). b[6]). b[4]). assign g3 = g1 | (p1 & g2). b. b[0]). a[2]. b[5]). xor(psum[5]. endmodule module kogge_stone(input input output output wire wire bit [7:0] a. bit c0. c7. b[6]). g. a[7]. a[5]. a[4]. or(p[3]. a[3]. bit [7:0] s. b[2]). and(g[4]. b[1]). and(g[1]. // operator "o" assign p3 = p1 & p2. a[0]. b[4]). a[1]. b[1]). b[4]). a[2]. xor(psum[0]. xor(psum[2]. a[4]. or(p[5]. generate and psum signals from the input operands or(p[0]. xor(psum[4]. a[7]. 20 .

g[1]. p30. g43. c6). p[2]. p74. g30. opo opo10(p54. endmodule 22 . g74). p52. g60). g65). g10). p10. opo opo09(p65. opo opo15(p63. g21. c7). of operator o g74. g20. g32. p30. g54. p43. g65. p41. g[1]. g[7]. g40 | (p40 & c0). opo opo13(p21. p[0]. p21. p65. g20 | (p20 & c0). g10 | (p10 & c0). c5). g[0]. opo opo06(p[2]. g20). p20. g32. p[5]. p60. g30). g[5]. p[3]. p32. g54). psum[0].SystemVerilog Code for Kogge-Stone Adder – Part 3 of 4 // first level of operator o opo opo01(p[7]. xor(s[7]. p63. g[5]. p10. g[3]. p50. p76. g52. psum[6]. g63). xor(s[4]. g43). opo opo12(p32. opo opo02(p[6]. g30 | (p30 & c0). opo opo16(p52. p[1]. opo opo17(p41. p32. g10. g[6]. g50). opo opo05(p[3]. g[3]. // third level opo opo14(p74. psum[3]. p21. p20. g60 | (p60 & c0). c0). c2). opo opo11(p43. c4). g21. p43. c1). p54. psum[1]. // form the sum signals xor(s[0]. g[4]. psum[5]. xor(s[3]. p70. g70 | (p70 & c0). p54. g[4]. g63. psum[4]. xor(s[2]. opo opo07(p[1]. g52). g70). psum[2]. g[2]. c3). p[4]. g40). g41). g43. g50 | (p50 & c0). p10. xor(s[1]. g76). g10. g[0]. 21 SystemVerilog Code for Kogge-Stone Adder – Part 4 of 4 // form the assign c1 = assign c2 = assign c3 = assign c4 = assign c5 = assign c6 = assign c7 = assign c8 = carry signals g[0] | (p[0] & c0). p[0]. opo opo03(p[5]. psum[7]. xor(s[5]. p40. g[6]. g[0]. g54. xor(s[6]. p[0]. opo opo04(p[4]. // second level of operator o opo opo08(p76. p[6]. g21). g41. g[2]. g76. g32).

logic c0. b = $random. c0. 45 + 1 = 235 (235) 24 . reg [8:0] check. c0. s}. b. decimal values including a check logic [7:0] a.A Testbench for the Kogge-Stone Adder module tb1ks. check = a + b + c0. // compute and display the sum every 10 time units #10 $display($time. " %d + %d + %d = %d (%d)". check). s. wire c8.. c0 = $random. // // // // // 8-bit carry 8-bit carry 9-bit inputs (to be chosen randomly) input (to be chosen randomly) sum output out of the MSB position sum value used to check correctness // instantiate the 8-bit Kogge-Stone adder kogge_stone ks1(a. {c8. b. a. wire [7:0] s. // random unsigned inputs. end 23 Part of the Testbench Output 10 36 + 129 + 1 = 166 (166) 20 30 40 50 60 70 80 90 100 99 + 101 + 13 + 1 = 113 (113) 18 + 1 = 120 (120) 13 + 118 + 1 = 132 (132) 237 + 140 + 1 = 378 (378) 198 + 197 + 0 = 395 (395) 229 + 119 + 0 = 348 (348) 143 + 242 + 0 = 385 (385) 232 + 197 + 0 = 429 (429) 189 + . c8). b. // simulation of 50 random addition operations initial repeat (50) begin // get new operand values and compute a check value a = $random..

Ladner-Fischer (LF) Architecture • The n-bit LF design also achieves the minimum logical depth of log2n levels. There are 3 other possible 8-bit designs. The 8-bit LF design is shown below: 25 Knowles Architecture • Knowles has shown that the KS and LF designs are limiting cases of a set of minimumdepth designs. such as: 26 . It uses higher fan-out configurations.

Han-Carlson (HC) Architecture • One additional stage at the end is used. Example: n=k--. Then. 27 Post-/Pre. First./Dec. • pre-increment Example: n=++k. the new value of k is assigned to n. The value of k is assigned to n and then k is decremented. but it has low fanout and few devices. Operators • post-increment Example: n=k++. Then. First. the new value of k is assigned to n. The value of k is assigned to n and then k is incremented.Inc. k is incremented. Example: n=--k. 28 • post-decrement • pre-decrement . k is decremented.

y = y / x. (%=. i .. is equiv. . i < 16. this variable is declared outside of the loop.. • -= operator: y -= x. to: is equiv.. |=. < 16. i = i + 1) • SystemVerilog allows declaration of a local loop variable: for (int i = 0.. . • etc. &=. y = y . to: y = y + x..x. to: is equiv. for (i = 0.. we need a variable which keeps track of the number of iterations which have been executed. y = y * x. 30 . ) 29 Declaring Local Loop Variables • In a for loop. i++) . ^=. • /= operator: y /= x. In Verilog. • *= operator: y *= x.. to: is equiv.. so it is not local to the loop: // Verilog example int i.Compound Assignment Operators • += operator: y += x.

h. • An example is as follows: struct { logic a. b. } my_structure. External declaration: If typedef is used outside of any module. Example: typdef reg [127:0] wide_word. 32 . e. bit [3:0] g. then it is only visible within that module. then it can be visible within several modules.User-Defined Data Types • The typedef keyword is used. • Useful for grouping together a set of signals which have different data types. int d. • It can be applied for either a single module or for several different modules: Local declaration: If typedef is used inside of a module. f. 31 Structures: The struct keyword • Similar to structures in C. c.

7. 34 . h. 4'hB}. 6. f. b. 33 Initialization of Structures • Initial values can be specified within curly braces by listing them in the order that they are declared within the structure: typedef struct { logic a. bit [3:0] g. 5.Structures – cont. 1'b1. For example: my_structure. int d. b. int d. • We can also combine struct and typedef to create new data types: typedef struct { logic a. c. c. 4'hA. } my_new_type. 1'b0. h. • Use the "dot notation" to access a particular element of a structure. e. my_new_type var1 = {1'b0. e. f.a = 1'b1. } my_new_type. bit [3:0] g.

Then. endmodule 36 . you can pass arguments to functions and tasks which are structures. 35 Example: A struct through a Module Port • First. Then. do the following: Place the typedef struct statement outside of the module.. . } simple. you can pass variables of that type into and out of the module. the module can declare one or more of its ports to be of that type..Structures Passed Through Module Ports • In order to be able to pass structures through the ports of a module. int c. b. • Similarly. typedef struct { logic [15:0] a. module example (input simple r. use a typedef struct statement outside of the module. s).

but unpacked unions are not synthesizable. sometimes the data is needed in one representation. Each representation may be of a different data type. • Packed unions are synthesizable.Packed Structures • You can declare a struct to be packed. 37 Unions • Similar to unions in C. but having more than one representation. Last element in the struct is the right-most element of the vector. This means that all of the elements in the struct are stored as contiguous bits which are stored as a vector: First element in the struct is the left-most element of the vector. In a typical application of a union. while at other times it is needed in a different representation. 38 . The number of bits in the vector is equal to the sum of the number of bits needed to hold each individual element of the struct. • A union represents a single unit of storage.

} info. $display("signed info: %d". logic signed [3:0] s. 39 Example of a Union – Continued module tbu.s = -3. end endmodule 40 . info. $display("unsigned info: %d". } info. logic signed [3:0] s.u). we want to be able to represent the information as either a signed or an unsigned quantity: union packed { logic [3:0] u.s).Example of a Packed Union • In the example below. // testbench for the union union packed { logic [3:0] u. info. initial begin info.

41 Arrays • Multi-dimensional arrays are allowed. just specify each of its index values. its value is 8+4+1=13. • To assign a value to a specific array element. • The same array can also be declared as follows: int my_array[16][8][4]. For example: my_array[4][3][2] = 55. • For example. 42 . a 3-dimensional array of integers of size 16x8x4 can be declared as: int my_array[0:15][0:7][0:3].Example of a Union – Continued • The output from executing the previous code: signed info: unsigned info: 13 -3 • Note that the value -3 is represented as a 4-bit signed binary number by: 1101 • When this 4-bit pattern is interpreted as an unsigned number.

1}}.'{1.Initializing Array Elements • The construction '{ . int e[2][4]. 20. . 40. 1. '{1. 20. we can use the default keyword: int c[100] = '{default:0}. 0. end 44 . int b[2][4] = '{'{0. f = '{100{0}}. • We can also use the replication operator: int c[100] = '{100{0}}. It can be used to initialize an array: int a[5] = '{10. 30. 50}. 43 Assigning Multiple Values to Arrays • We can also use array literals and the replication operator to assign constant values to arrays which have already been declared: int d[5]. } is called an array literal. 1}}. 40. initial begin d = '{10. e = '{'{0. // all 0s • Alternatively . 30. 1. 0. 50}. 0. 1. int f[100].. 1. 0}. . 0}. 0..

end 45 Using foreach Loops with Arrays • A foreach loop automatically goes through each possible index value in an array. • The previous example can be coded as: int arr[10]. initial begin foreach (arr[i]) arr[i] = 3*i.Using for Loops with Arrays • Some features of SystemVerilog make using for loops with arrays easier than in Verilog: Declare the loop index directly in the loop. initial begin for (int i = 0. Use the ++ increment operator Use the $size function (returns the number of array elements) int arr[10]. i < $size(arr). end 46 . i++) arr[i] = 3*i.

} collection. [k] in the foreach statement: int g[10][10]. end 47 Arrays of Structures • We can form an array in which each element is a structure: // create the structure typedef struct { int a. initial begin foreach (g[i. logic [15:0] d. k] rather than [i] .. form an array of 50 of these collection coll_arr[50]. e. j]) g[i][j] = i + j.. // now. .foreach with Multidimensional Arrays • The syntax is a little unusual when using foreach with a multidimensional array. f. We use [i. 48 . b.... c.

e. Beijing. b[10]. followed by the name of the variable. sub. • Can also use it together with a typedef: typedef enum {add. as in the following type definition: // this contains 3 10-element arrays typedef struct { int a[10]. 50 . c[10]. logic [15:0] d.Structures Containing Arrays • It is also possible to include one or more arrays as part of a structure. 49 Enumerated Names and Data Types • Useful for abstract system modeling. • The enum keyword is used. followed by a list of the allowed values. } new_collection. f. Nanjing} city. mul} instruction. For example: enum {Shanghai.

• If desired. it is difficult for other people reading the code to determine what the designer intended. which corresponds to the int data type. 51 Procedural Blocks: Problem with always • In Verilog. • Also.Values of Enumerated Type Variables • By default. The first name listed gets the value 0. etc. The second name listed gets the value 1. the rules are complex and the designer can easily make a mistake. the actual values used internally to represent the different enumerated names are 32-bit 2-state values. 52 . latches or flip-flops when it is synthesized: signals and qualifiers in the sensitivity list statements within the body of the always block • However. it is possible to override this default value assignment process. an always block can be used to model either combinational logic or sequential logic. • The designer must observe a set of rules order to specify if the block will generate combinational logic.

• The block is also evaluated once at simulation time 0 so that the combinational logic block is properly initialized.Expressing Combinational Logic: always_comb • The always_comb statement expresses the designer's intent to create a combinational logic block. the block will be evaluated whenever any input signal to the block changes. else mux_out = in0. select signal select and output mux_out can be modeled as follows (the inferred sensitivity list includes in0. 53 always_comb Example • A 2-to-1 MUX with data inputs in0 and in1. in1 and select): always_comb if (select) mux_out = in1. 54 . • You do not include a sensitivity list! (The sensitivity list is "inferred" to include all the necessary signals in the block. This corresponds to the way in which a combinational logic block operates. • Synthesis tools can issue a warning message if the code generates any sequential elements.) Thus.

This corresponds to the way in which a latched logic block operates. Every signal in this list must be qualified by the keyword posedge or negedge. • You do not include a sensitivity list! (The sensitivity list is "inferred" to include all the necessary signals in the block.) Thus. 55 Expressing Latched Logic: always_latch • The always_latch statement expresses the designer's intent to create a latched (i..e. level-sensitive) sequential logic block. 56 . • Example (a rising edge triggered D-type flip-flop with an active-low asynchronous reset) : always_ff @(posedge clk or negedge rst) if (rst == 0) Q <= 0. else Q <= D.Expressing Edge-Triggered Logic: always_ff • The always_ff statement expresses the designer's intent to create an edge-triggered sequential logic block. the block will be evaluated whenever any input signal to the block changes. • You do include a sensitivity list. • Synthesis tools can issue a warning message if the code generates any other type of block. • Synthesis tools can issue a warning message if the code generates any other type of block. • The block is also evaluated once at simulation time 0 so that the latched logic block is properly initialized.

. • As in Verilog. Those statements will be executed sequentially. • Note that this uses an "incompletely specified" if statement since there is no else clause. 58 . end is not required in functions containing multiple statements. • This will synthesize a latch. The blocking assignment = must be used in each of the statements. you can use a return statement to return a value. which is consistent with the designers intent as expressed by the always_latch keyword. you can assign the value to be returned to the name of the function.always_latch Example • A D-type latch which is transparent when the clock is high can be expressed as: always_latch if (clock) Q <= D.. 57 Functions • begin . • Alternatively.

Example of Using return • A simple example using the return statement: // perform a multiply-add operation function int mul_add (input int a. return(a*b + c). depending on the desired behavior. • This provides an efficient way to have several different exit paths from the function. b. (In other words. • If a return statement is executed. depending on the placement of the return. b. mul_add = a*b + c. • It is also OK to have more than one return statement. the function is terminated at that point. c). endfunction 59 Placement of the return Statement • The return statement does not have to be placed at the end of the function. not all statements in the function may be executed. c). endfunction • Same result using the Verilog-style assignment: // equivalent operation function int mul_add (input int a.) 60 .

• SystemVerilog Tutorials. Specification. Springer. Sutherland. IEEE Std 1800TM-2005. Spear. Doulos Ltd.com/systemverilog/ 61 . and Verification Language. 2004. Davidmann and P. 2006.. • C. electroSofts.doulos. http://www. Flake.com/knowhow/sysverilog/tutorial/ • SystemVerilog Tutorial. SystemVerilog for Design. • S. 22 November 2005. Kluwer Academic Publishers. http://electrosofts. IEEE. S.com. SystemVerilog for Verification.References • IEEE Standard for SystemVerilog— Unified Hardware Design.