当前位置:网站首页>[quick start of Digital IC Verification] 15. Basic syntax of SystemVerilog learning 2 (operators, type conversion, loops, task/function... Including practical exercises)

[quick start of Digital IC Verification] 15. Basic syntax of SystemVerilog learning 2 (operators, type conversion, loops, task/function... Including practical exercises)

2022-07-07 08:00:00 luoganttcc

Reading guide : The author has the honor to be a pioneer in the field of electronic information in China “ University of electronic technology ” During postgraduate study , Touch the cutting edge Numbers IC Verification knowledge , I heard something like Huawei Hisilicon Tsinghua purple light MediaTek technology And other top IC related enterprises in the industry , Pairs of numbers IC Verify some knowledge accumulation and learning experience . Want to get started for help IC Verified friends , After one or two thoughts , This column is specially opened , In order to spend the shortest time , Take the least detours , Most learned IC Verify technical knowledge .

List of articles

One 、 Description of content

  • SystemVerilog The operator
  • SystemVerilog Procedure statement
  • SystemVerilog Variable type conversion
  • SystemVerilog Loop control statement
  • SystemVerilog enhance case sentence
  • SystemVerilog Mission (task) And the function (function)

Two 、 The operator (Operation)

 Insert picture description here

  • All equal to === I will also compare x/z

3、 ... and 、SystemVerilog Procedure statement (Procedural Statements)

3.1、 Autoincrement and autodecrement operators

  • similar C Language

 Insert picture description here

  • First increase / Use after reduction and use before increase / reduce

 Insert picture description here

notes :SystemVerilog Self increase and self decrease of are usually used in TB in , Will not be used in RTL In the code !

 Insert picture description here

3.2、 Logical comparison operator

  • be equal to ==, It's not equal to !=( It's used a lot , Generally speaking, there are x There is something wrong with the state )

    • Logical truth 1, Logic assumes that 0;
    • If the compared value There is x and z, Then the logical value is 1’bx
      • eg:a=4'b000x and b=4'b000x The two comparison results are 1'bx, Then there is a pit here if if(a == b), Be careful 1'bx Is it true !
  • Congruence ===, Incongruence !==

    • perfect match Four state values :0,1,x,z
      • eg:a=4'b000x and b=4'b000x The two comparison results are 1'b1
  • Wildcard logical comparison

    • Match, etc ==? And match !=?
      • Compare by bit , hold x and z Value should be matched
      • Just put Right operand Medium x and z As a shielding symbol
        • eg:4‘b1010 ==? 4'b101x Match and return 1'b1;4‘b1011 ==? 4'b101x Match and return 1'b1

 Insert picture description here

 Insert picture description here

  • Examples of logical comparison of matchers

 Insert picture description here

  • Print out the first $display

notes : The comments in the screenshot above and display There is a slight problem with grammar .

3.3、inside keyword

  • inside Sure Match any value in a set of data range

 Insert picture description here

Four 、 Variable Type conversion (Type Casting)

4.1、 Variable type converter type' (expression)

  • SystemVerilog Added Variable type converter type' (expression)
    • The variable type converter can type the expression at any time
    • Not like Verilog The same can only happen in assignment statements

 Insert picture description here

4.2、$cast Cast

 Insert picture description here

  • $cast(fsm, 1+2): hold 3 Assign a value to fsm, And convert the integer mandatory type to the enumeration type , Is this time fsm by DATA

4.3、 Variable bit width conversion (Size Casting)

  • SystemVerilog Added Vector bit width transformation size' (expression)
    • The expression is converted to Small Bit width hour , Left The bits on the side are Delete
    • The expression is converted to Big Bit width hour , Left The bits on the side are expand

 Insert picture description here

4.4、 Variable sign bit conversion

  • SystemVerilog Sign bits can be converted signed' (expression) and unsigned' (expression)
    • Operand sign bit conversion
    • Expression result sign bit conversion

 Insert picture description here

5、 ... and 、SystemVerilog Loop control statement

5.1、for Loop statement

  • Verilog The loop variable in must be in for Statement

    • The current loop interacts with other statements
  • SystemVerilog Can be in for Loop variables are declared inside the loop

    • Each variable is a unique local variable , So variables with the same name used externally will not affect each other
    • Local loop variables are automated (automatic)
    • for The local variables declared inside the loop do not exist outside the loop statement

 Insert picture description here

  • stay Verilog Both combinatorial logic and temporal logic are described in always keyword , Sequential logic always @(posedge clk); Combinatorial logic always @(*)
  • stay SystemVerilog in , Describe temporal logic with always_ff @(posedge clk) perhaps always @(posedge clk); Combinatorial logic always_comb @(*) or always @(*)

 Insert picture description here

  • continue

    • Can only be used for circular statements
    • End this cycle , So let's go to the next loop
  • break

    • Can only be used for circular statements
    • Break the cycle , Out of the loop , Do not execute this loop statement
  • return

    • Can be used for loop statements
      • End of cycle
    • It can also be used for task and function
      • end task and function

5.2、do...while Loop statement

  • Verilog Medium while The loop does not necessarily execute
    • If the value of the first loop expression is false , Then the loop statement will not execute
  • SystemVerilog Added do...while Loop statement ( similar C Language )
    • Execute the loop statement at least once
    • Judge the loop variable at the end of the loop statement

 Insert picture description here

5.3、SystemVerilog enhance case sentence - case/casex/casez

  • default Optional. , In a case In the sentence Cannot use more than one default
  • First calculate case Value of expression , Then match with the actual branch below , When the match is reached, the corresponding statement will be executed
  • case The value of the expression is Assign by bit , Can handle x and z

 Insert picture description here

  • casez
    • No concern z

 Insert picture description here

notes : Question marks indicate wildcards

  • casex
    • No concern z and x

 Insert picture description here

  • When field = 8'b01100110 when ,casex Select branch statement2 perform
  • field ^ mask = x1x0x1x0

6、 ... and 、SystemVerilog Mission (task) And the function (function)

6.1、Verilog task and function summary

  • function

    • Function execution time No simulation time is consumed
    • Function There cannot be a statement that controls the simulation time
      • No simulation time delay :#100 =(`timescale 1ns/10ps)
      • There must be no blocking statements :@(posedge clock) perhaps wait(ready)
      • Cannot call task
  • void function no return value

    • Verilog Of function There must be a return value (Verilog Return by function name !)

 Insert picture description here

function int sum(input x, y);
	sum = x + y;
	return sum;
endfunction

 
  
  • 1
  • 2
  • 3
  • 4
  • task
    • task contain input、output and inout sentence
    • task Consume simulation time
      • Delay :#20
      • Clock cycle :@(posedge clock)
      • event :event

 Insert picture description here

6.2、SystemVerilog task and function

  • tasks and function
    • No Need to use begin…end sentence
    • Added return sentence
      • The return value is only 1 with return; return bit/logic This simple type of variable
    • void function no return value
    • function There can be output and inout As a formal parameter
      • Return value greater than 1 Time , use output It is convenient to return ; return array/queue/struct Complicated use output

 Insert picture description here

You can make an analogy like this ,function Without timing information , Generally speaking, describe combinatorial logic ;task You can bring timing information , It can describe combinatorial logic , It can also describe temporal logic !

  • return sentence
    • SystemVerilog Added return sentence
    • return Statement execution time Returns the value of an expression , Otherwise, the last returned value Assign to function name
    • return Statement is used to exit task and function

 Insert picture description here

  • void function
    • void function no return value
    • output and inout The formal parameters are void function Provides a way to pass variables
    • void function Can be like task The same is called , But it must be consistent with the content constraints of the function

 Insert picture description here

  • Pass by name task and function Parameters
    • SystemVerilog Pass the parameter by the name of the formal parameter
      • Reduce errors
    • The order of parameters is unlimited
    • The syntax of passing parameters is the same as Verilog The way of port connection is the same

 Insert picture description here

SystemVerilog Enhance function formal parameters

  • Added input and output

 Insert picture description here

Default direction and type of formal parameters

  • Each formal parameter has a default type
  • call task and function when , It is not necessary to pass parameters to parameters with default parameter values
    • If the parameter value is not passed , The default value will be used

 Insert picture description here

eg:

always_ff @(posedge clock)
	result = incrementer(data_bus);// Parameters that are not explicitly passed use default values , namely result = data_bus + 1;

 
  
  • 1
  • 2

Using a reference (reference) Pass parameters instead of copying

  • Common tasks (task) And the function (function) The method of passing parameter values is Copy
  • Using a reference (reference) The way is explicit to the task (task) And the function (function) Pass parameters
    • Keywords are :ref( To replace the input, output perhaps inout)
    • Only automatic (automatic) Tasks and functions can be used ref Parameters

 Insert picture description here

  • (8*i)+:8 Medium : meaning : hold for Loop unrolling , For example, when i=0 when ,(8*0)+:8 Express 0:0+8(0:8); When i Of =1 when ,(8*1)+:8 Express 8:16, This way for loop , Ergodic data[63:0]
  • There are three ways to express a vector :[MSB:LSB][MSB-:WIDTH][LSB+:WIDTH], For example, it corresponds to [7:0][7-:8][7:0])、[0+:8][0:7]

Using a reference (reference) Pass parameters instead of copying

  • Parameters passed by reference can be read-only (read-only)
    • allow task/function Reference information within the scope of the call
    • prevent task/function Modify referenced information
  • modify task ref Parameters are very sensitive
  • ref Parameter can read the current value
  • ref Parameters can immediately convey changes in information

 Insert picture description here

Parameter passing

  • The parameter type is consistent with the parameter type on the left by default
  • input - By default , Enter a copy of the value at the beginning
  • output - At the end of the output, copy a copy of the value
  • inout - At the beginning, enter , Output at the end , A copy of the value
  • ref - Pass by reference , The effect immediately appears
    • When passing an array to task and function when , It can save time and content
  • const - Parameter cannot be modified

 Insert picture description here
Frequently asked questions :task and function difference ?

  • a. Whether it consumes simulation time , namely task There can be statements that consume simulation time ,function There can be no time consuming statements ,task It does not necessarily consume simulation time .
  • b. task You can call function,function Cannot call task.
  • c. stay verilog in : task Multiple values can be returned (output),function Only one value can be returned
  • d. task It's not return Of , void function Also no return Of

task and function Whether it can be integrated ?

  • Can it be integrated , Depending on the user, the statement inside is RTL Behavior level description
  • such as task or function There is $display("xxx");, So this task or function It must not be integrated .wait/#10 And so on cannot be integrated !

7、 ... and 、 Practice

7.1 Practice logical operators and arithmetic operators

7.1.1、 Comparison operator demo

sv_operation.sv

module SV_OPERATION();
  bit sig_a;
  bit sig_lgc_inv_a;
  bit sig_bit_inv_a;
  bit [2:0] sig_m_a;
  bit [2:0] sig_m_lgc_inv_a;
  bit [2:0] sig_m_bit_inv_a;
  bit signed [7:0] sig_c;
  bit signed [7:0] sig_lgc_lft_c;
  bit signed [7:0] sig_lgc_rgt_c;
  bit signed [7:0] sig_arth_lft_c;
  bit signed [7:0] sig_arth_rgt_c;
  int i;
  logic [7:0] comp_a;
  logic [7:0] comp_b;
  logic [2:0] a;
  logic       comp1 [8];
  logic       comp2 [8];
  initial begin
    sig_a = 1'b0; sig_m_a = 3'b010;
    sig_c = 8'sb1100_0111; sig_lgc_inv_a = !sig_a; sig_bit_inv_a = ~sig_a; sig_m_lgc_inv_a = !sig_m_a; sig_m_bit_inv_a = ~sig_m_a; comp_a = 8'b0100_1101;
    comp_b = 8'b0100_1100; if(comp_a == comp_b) begin $display("******comp_a: %b == comp_b: %b", comp_a, comp_b); end else begin $display("******comp_a: %b != comp_b: %b", comp_a, comp_b); end if(comp_a === {comp_b[7:1], 1'bx}) begin
      $display("******comp_a: %b === {comp_b[7:1], 1'bx}: %b", comp_a, {
    comp_b[7:1], 1'bx}); end else begin $display("******comp_a: %b !== {comp_b[7:1], 1'bx}: %b", comp_a, {comp_b[7:1], 1'bx}); end if(comp_a ==? {comp_b[7:1], 1'bx}) begin $display("******comp_a: %b ==? {
    comp_b[7:1], 1'bx}: %b", comp_a, {comp_b[7:1], 1'bx});
    end
    else begin
      $display("******comp_a: %b !=? {comp_b[7:1], 1'bx}: %b", comp_a, {
    comp_b[7:1], 1'bx});
    end
  end 
endmodule 

rslt.log

******comp_a: 01001101 != comp_b: 01001100
******comp_a: 01001101 !== {
    comp_b[7:1], 1'bx}: 0100110x ******comp_a: 01001101 ==? {comp_b[7:1], 1'bx}: 0100110x

 
  
  • 1
  • 2
  • 3
  • Makefile Same as The first 14 Blog post , But is comp_file Parameters changed :make comp_file=sv_operation.sv
  • sig_a It means single bit ,sig_m_a Indicates multiple bits
  • sig_c = 8'sb1100_0111; Medium s It means that there is a sign
  • Single bit logic negates ! And bitwise inversion ~ equally ; But multi bits are different !
  • comp_xxx Represents the variable used for comparison

7.1.2、 Logical operators ! And arithmetic operators ~ The difference of demo

sv_operation.sv

    $display("******single bit logic invertor ! :sig_a is : %b, sig_lgc_inv_a is : %b", sig_a, sig_lgc_inv_a);
    $display("******single bit bit invertor ~ :sig_a is : %b, sig_bit_inv_a is : %b", sig_a, sig_bit_inv_a);
    $display("******multiple bit logic invertor ! :sig_m_a is : %b, sig_m_lgc_inv_a is : %b", sig_m_a, sig_m_lgc_inv_a);
    $display("******multiple bit bit invertor ~ :sig_m_a is : %b, sig_m_bit_inv_a is : %b", sig_m_a, sig_m_bit_inv_a);

rslt.log

******single bit logic invertor ! :sig_a is : 0, sig_lgc_inv_a is : 1
******single bit bit   invertor ~ :sig_a is : 0, sig_bit_inv_a is : 1
******multiple bit logic invertor ! :sig_m_a is : 010, sig_m_lgc_inv_a is : 000
******multiple bit bit   invertor ~ :sig_m_a is : 010, sig_m_bit_inv_a is : 101
  • For single bit logic, negate ! And bitwise inversion ~ No difference ; And multi bits are different

7.1.3、 Shift operation demo

sv_operation.sv

    sig_lgc_lft_c  = sig_c <<  5;
    sig_lgc_rgt_c  = sig_c >>  5;
    sig_arth_lft_c = sig_c <<< 5;
    sig_arth_rgt_c = sig_c >>> 5;
    $display("******logical left shift << :sig_c is : %b, sig_lgc_lft_c is : %b", sig_c,sig_lgc_lft_c);
    $display("******logical right shift >> :sig_c is : %b, sig_lgc_rgt_c is : %b", sig_c,sig_lgc_rgt_c);
    $display("******arithmetic left shift <<< :sig_c is : %b, sig_arth_lft_c is : %b", sig_c,sig_arth_lft_c);
    $display("******arithmetic right shift >>> :sig_c is : %b, sig_arth_rgt_c is : %b", sig_c,sig_arth_rgt_c);

rslt.log

******logical left  shift       <<      :sig_c is : 11000111, sig_lgc_lft_c is : 11100000
******logical right shift       >>      :sig_c is : 11000111, sig_lgc_rgt_c is : 00000110
******arithmetic left shift     <<<     :sig_c is : 11000111, sig_arth_lft_c is : 11100000
******arithmetic right shift    >>>     :sig_c is : 11000111, sig_arth_rgt_c is : 11111110
  • Logic shift left / Move right , After moving, use 0 To mend
  • Arithmetic left shift is the same as logical left shift ; Move arithmetic right if the highest bit is 1, Then make up 1. Similarly, if the highest bit is 0, Then make up 0

7.1.4、++i and i++ difference demo

sv_operation.sv

    i = 0;
    while(i++ < 5) begin
      $display("****** the i++ i %d", i);
    end
    i = 0;
    while(++i < 5) begin
      $display("****** the ++i i %d", i);
    end

 
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

rslt.log

****** the i++ i           1
****** the i++ i           2
****** the i++ i           3
****** the i++ i           4
****** the i++ i           5

****** the ++i i 1
****** the ++i i 2
****** the ++i i 3
****** the ++i i 4

7.1.5、inside keyword demo

sv_operation.sv

    for(int i=0; i<8; i++) begin
      a = i[2:0];
      if(a==3'b100 || a==3'b101 || a==3'b011) begin comp1[i] = 1'b1;
      end
      else begin
        comp1[i] = 1'b0; end if(a inside{3'b100, 3'b101, 3'b011}) begin
        comp2[i] = 1'b1; end else begin comp2[i] = 1'b0;
      end
    end
    if(comp1 == comp2) begin
      $display("******comp1 == comp2");
    end
    else begin
      $display("******comp1 != comp2");
    end

rslt.log

******comp1 == comp2

  
   
  • 1

7.2、 Circulation practice

7.2.1、 Different initial Blocks share the same global variable demo

sv_loop_case.sv

module sv_loop_case();
int j;
int i;
initial begin : loop0
  for(i=0; i<5; i++) begin
    #1;
    $display("******loop0 i = %0d", i);
  end
end
initial begin : loop1
  for(i=0; i<5; i++) begin
    #1;
    $display("******loop1 i = %0d", i);
  end
end
endmodule 
******loop0 i = 0
******loop1 i = 1
******loop0 i = 2
******loop1 i = 3
******loop0 i = 4
******loop1 i = 5


 
  
  • You can see two initial Blocks share the same global variable i,for Circulation has an effect !

7.2.2、 Different initial Blocks use local variables demo

sv_loop_case.sv

module sv_loop_case();
//int j;
//int i;
initial begin : loop0
  for(int i=0; i<5; i++) begin // Notice that it defines int, This is called a local variable !
    #1;
    $display("******loop0 i = %0d", i);
  end
end
initial begin : loop1
  for(int i=0; i<5; i++) begin
    #1;
    $display("******loop1 i = %0d", i);
  end
end
endmodule 

rslt.log

******loop0 i = 0
******loop1 i = 0
******loop0 i = 1
******loop1 i = 1
******loop0 i = 2
******loop1 i = 2
******loop0 i = 3
******loop1 i = 3
******loop0 i = 4
******loop1 i = 4


   
    
  • You can see two intial The block for Circulation does not affect !

7.2.3、 Different initial Block use automatic Defining variables demo

sv_loop_case.sv

module sv_loop_case();
//int j;
//int i;
initial begin : loop0
  automatic int i;
  for(i=0; i<5; i++) begin
    #1;
    $display("******loop0 i = %0d", i);
  end
end
initial begin : loop1
  automatic int i;
  for(int i=0; i<5; i++) begin
    #1;
    $display("******loop1 i = %0d", i);
  end
end


endmodule 

rslt.log

******loop0 i = 0
******loop1 i = 0
******loop0 i = 1
******loop1 i = 1
******loop0 i = 2
******loop1 i = 2
******loop0 i = 3
******loop1 i = 3
******loop0 i = 4
******loop1 i = 4


     
      
  • You can see the use of automatic Defining variables has the same effect as using local variables , Two initial The block for Cycles also do not affect each other

7.2.4、while and do...while Execution process demo

sv_loop_case.sv

initial begin
  j = 0;
  do begin
    $display("******%d th loop in do while loop", j);
    j++;
  end
  while(j<0);

  j=0;
  while(j<0) begin
    $display("******%d th loop in while loop", j);
    j++;
  end
end 

rslt.log

******          0 th loop in do while loop

       
        
  • 1
  • You can see do...while I'm going to execute it first , Then judge

7.3、case/casez/casex Branch differentiation exercise

sv_loop_case.sv

logic [3:0] sel_z = 4'bz01z; logic [3:0] sel_x = 4'bx01x;
initial begin
  case(sel_z)
    4'b1??? : $display("****** sel_z(%0b) is 4'b1??? in case selection", sel_z); 4'b01?? : $display("****** sel_z(%0b) is 4'b01?? in case selection", sel_z); 4'b001? : $display("****** sel_z(%0b) is 4'b001? in case selection", sel_z);
    4'b0001 : $display("****** sel_z(%0b) is 4'b0001 in case selection", sel_z); default : $display("****** sel_z(%0b) is in default branch in case selection", sel_z); endcase casez(sel_z) 4'b1??? : $display("****** sel_z(%0b) is 4'b1??? in casez selection", sel_z); 4'b01?? : $display("****** sel_z(%0b) is 4'b01?? in casez selection", sel_z);
    4'b001? : $display("****** sel_z(%0b) is 4'b001? in casez selection", sel_z); 4'b0001 : $display("****** sel_z(%0b) is 4'b0001 in casez selection", sel_z); default : $display("****** sel_z(%0b) is in default branch in case selection", sel_z); endcase case(sel_x) 4'b1??? : $display("****** sel_x(%0b) is 4'b1??? in case selection", sel_x);
      4'b01?? : $display("****** sel_x(%0b) is 4'b01?? in case selection", sel_x); 4'b001? : $display("****** sel_x(%0b) is 4'b001? in case selection", sel_x); 4'b0001 : $display("****** sel_x(%0b) is 4'b0001 in case selection", sel_x);
      default : $display("****** sel_x(%0b) is in default branch in case selection", sel_x);
    endcase
    casex(sel_x)
      4'b1??? : $display("****** sel_x(%0b) is 4'b1??? in casex selection", sel_x); 4'b01?? : $display("****** sel_x(%0b) is 4'b01?? in casex selection", sel_x); 4'b001? : $display("****** sel_x(%0b) is 4'b001? in casex selection", sel_x);
      4'b0001 : $display("****** sel_x(%0b) is 4'b0001 in casex selection", sel_x); default : $display("****** sel_x(%0b) is in default branch in case selection", sel_x);
    endcase
end

rslt.log

****** sel_z(z01z) is in default branch in case selection
****** sel_z(z01z) is 4'b1??? in casez selection ****** sel_x(x01x) is in default branch in case selection ****** sel_x(x01x) is 4'b1??? in casex selection

 
  
  • 1
  • 2
  • 3
  • 4
  • casez No concern z, namely z Can be regarded as 0 or 1.
  • casex No concern z and x, namely x and z Can be regarded as 0 or 1.
  • Question marks indicate wildcards ,case Inside the general configuration ?, Only for 0 and 1;casez Inside ? Pass through , Can represent 0/1/z;casex Inside ? Pass through , Can represent 0/1/x/z.
  • z01z and 001? It can also be matched , But it has matched the previous 1???, So the back 001? It doesn't match anymore
  • stay case in , If one branch is z01z, that sel_z It can match this branch , Strictly match !

7.4、task/function practice

7.4.1、function Package structure demo

sv_function_task.sv

module sv_function_task();
typedef struct {
    
  int height;
  int weight;
  logic [7:0] legs;
  logic [1:0] hands;
  logic [1:0] eyes;
  logic       noses;
}animal;
animal duck;
animal dog;
animal d;
logic [76:0] data_in;
string name;
initial begin
  duck.height = 32'd132; duck.weight = 32'd200;
  duck.legs   = 8'd2; duck.hands = 2'd2;
  duck.eyes   = 2'd2; duck.noses = 1'd1;
  $display("******@%0tns duck unpacked value ******", $time);
  $display("******@%0tns duck height : %0d ****", $time, duck.height);
  $display("******@%0tns duck weight : %0d ****", $time, duck.weight);
  $display("******@%0tns duck legs : %0d ****", $time, duck.legs);
  $display("******@%0tns duck hands : %0d ****", $time, duck.hands);
  $display("******@%0tns duck eyes : %0d ****", $time, duck.eyes);
  $display("******@%0tns duck noses : %0d ****", $time, duck.noses);
  dog.height = 32'd232; dog.weight = 32'd100;
  dog.legs   = 8'd4; dog.hands = 2'd0;
  dog.eyes   = 2'd2; dog.noses = 1'd1;
  $display("******@%0tns dog unpacked value ******", $time);
  $display("******@%0tns dog height : %0d ****", $time, dog.height);
  $display("******@%0tns dog weight : %0d ****", $time, dog.weight);
  $display("******@%0tns dog legs : %0d ****", $time, dog.legs);
  $display("******@%0tns dog hands : %0d ****", $time, dog.hands);
  $display("******@%0tns dog eyes : %0d ****", $time, dog.eyes);
  $display("******@%0tns dog noses : %0d ****", $time, dog.noses);
end
function void animal_assign (input [76:0] data_in, output animal animal_obj);
  animal_obj.height  =  data_in[76 -: 32];
  animal_obj.weight  =  data_in[76-32 -: 32];
  animal_obj.legs    =  data_in[76-32-32 -: 8];
  animal_obj.hands   =  data_in[76-32-32-8 -: 2];
  animal_obj.eyes    =  data_in[76-32-32-8-2 -: 2];
  animal_obj.noses   =  data_in[0];
endfunction
function void animal_display (input string name, input animal animal_obj);
  $display("******@%0tns %s unpacked value animal_assign&animal_display******", $time, name);
  $display("******@%0tns %s height : %0d ****",$time, name, animal_obj.height);
  $display("******@%0tns %s weight : %0d ****",$time, name, animal_obj.weight);
  $display("******@%0tns %s legs : %0d ****",$time, name, animal_obj.legs);
  $display("******@%0tns %s hands : %0d ****",$time, name, animal_obj.hands);
  $display("******@%0tns %s eyes : %0d ****",$time, name, animal_obj.eyes);
  $display("******@%0tns %s noses : %0d ****",$time, name, animal_obj.noses);
endfunction
initial begin
  data_in = {
    32'd132, 32'd200, 8'd2, 2'd2, 2'd2, 1'd1};
  animal_assign(data_in, duck);
  name="duck";
  animal_display(name, duck);
  data_in = {
    32'd132, 32'd100, 8'd2, 2'd0, 2'd2, 1'd1};
  animal_assign(data_in, dog);
  name="dog";
  animal_display(name, dog);
end 
endmodule 

rslt.log

******@0ns duck unpacked value ******
******@0ns duck height   :  132 ****
******@0ns duck weight   :  200 ****
******@0ns duck legs     :  2 ****
******@0ns duck hands    :  2 ****
******@0ns duck eyes     :  2 ****
******@0ns duck noses    :  1 ****
******@0ns dog unpacked value ******
******@0ns dog height   :  232 ****
******@0ns dog weight   :  100 ****
******@0ns dog legs     :  4 ****
******@0ns dog hands    :  0 ****
******@0ns dog eyes     :  2 ****
******@0ns dog noses    :  1 ****
******@0ns duck unpacked value animal_assign&animal_display******
******@0ns duck height   :  132 ****
******@0ns duck weight   :  200 ****
******@0ns duck legs     :  2 ****
******@0ns duck hands    :  2 ****
******@0ns duck eyes     :  2 ****
******@0ns duck noses    :  1 ****
******@0ns dog unpacked value animal_assign&animal_display******
******@0ns dog height   :  132 ****
******@0ns dog weight   :  100 ****
******@0ns dog legs     :  2 ****
******@0ns dog hands    :  0 ****
******@0ns dog eyes     :  2 ****
******@0ns dog noses    :  1 ****

7.4.2、ref Parameters demo

sv_function_task.sv


module sv_function_task();
typedef struct {
    
  int height;
  int weight;
  logic [7:0] legs;
  logic [1:0] hands;
  logic [1:0] eyes;
  logic       noses;
}animal;
animal duck;
animal dog;
animal d;
logic [76:0] data_in;
string name;
/*initial begin
  duck.height = 32'd132; duck.weight = 32'd200;
  duck.legs   = 8'd2; duck.hands = 2'd2;
  duck.eyes   = 2'd2; duck.noses = 1'd1;
  $display("******@%0tns duck unpacked value ******", $time);
  $display("******@%0tns duck height : %0d ****", $time, duck.height);
  $display("******@%0tns duck weight : %0d ****", $time, duck.weight);
  $display("******@%0tns duck legs : %0d ****", $time, duck.legs);
  $display("******@%0tns duck hands : %0d ****", $time, duck.hands);
  $display("******@%0tns duck eyes : %0d ****", $time, duck.eyes);
  $display("******@%0tns duck noses : %0d ****", $time, duck.noses);
  dog.height = 32'd232; dog.weight = 32'd100;
  dog.legs   = 8'd4; dog.hands = 2'd0;
  dog.eyes   = 2'd2; dog.noses = 1'd1;
  $display("******@%0tns dog unpacked value ******", $time);
  $display("******@%0tns dog height : %0d ****", $time, dog.height);
  $display("******@%0tns dog weight : %0d ****", $time, dog.weight);
  $display("******@%0tns dog legs : %0d ****", $time, dog.legs);
  $display("******@%0tns dog hands : %0d ****", $time, dog.hands);
  $display("******@%0tns dog eyes : %0d ****", $time, dog.eyes);
  $display("******@%0tns dog noses : %0d ****", $time, dog.noses);
end
function void animal_assign (input [76:0] data_in, output animal animal_obj);
  animal_obj.height  =  data_in[76 -: 32];
  animal_obj.weight  =  data_in[76-32 -: 32];
  animal_obj.legs    =  data_in[76-32-32 -: 8];
  animal_obj.hands   =  data_in[76-32-32-8 -: 2];
  animal_obj.eyes    =  data_in[76-32-32-8-2 -: 2];
  animal_obj.noses   =  data_in[0];
endfunction
function void animal_display (input string name, input animal animal_obj);
  $display("******@%0tns %s unpacked value animal_assign&animal_display******", $time, name);
  $display("******@%0tns %s height : %0d ****",$time, name, animal_obj.height);
  $display("******@%0tns %s weight : %0d ****",$time, name, animal_obj.weight);
  $display("******@%0tns %s legs : %0d ****",$time, name, animal_obj.legs);
  $display("******@%0tns %s hands : %0d ****",$time, name, animal_obj.hands);
  $display("******@%0tns %s eyes : %0d ****",$time, name, animal_obj.eyes);
  $display("******@%0tns %s noses : %0d ****",$time, name, animal_obj.noses);
endfunction
initial begin
  data_in = {
    32'd132, 32'd200, 8'd2, 2'd2, 2'd2, 1'd1};
  animal_assign(data_in, duck);
  name="duck";
  animal_display(name, duck);
  data_in = {
    32'd132, 32'd100, 8'd2, 2'd0, 2'd2, 1'd1};
  animal_assign(data_in, dog);
  name="dog";
  animal_display(name, dog);
end*/
task automatic animal_assign(ref [76:0] data_in, ref animal animal_obj);
  animal_obj.height  =  data_in[76 -: 32];
  animal_obj.weight  =  data_in[76-32 -: 32];
  animal_obj.legs    =  data_in[76-32-32 -: 8];
  animal_obj.hands   =  data_in[76-32-32-8 -: 2];
  animal_obj.eyes    =  data_in[76-32-32-8-2 -: 2];
  animal_obj.noses   =  data_in[0];
endtask
task automatic animal_display(ref string name, ref animal animal_obj);
  $display("******@%0tns %s unpacked value automatic animal_assign&animal_display******", $time, name);
  $display("******@%0tns %s height : %0d ****",$time, name, animal_obj.height);
  $display("******@%0tns %s weight : %0d ****",$time, name, animal_obj.weight);
  $display("******@%0tns %s legs : %0d ****",$time, name, animal_obj.legs);
  $display("******@%0tns %s hands : %0d ****",$time, name, animal_obj.hands);
  $display("******@%0tns %s eyes : %0d ****",$time, name, animal_obj.eyes);
  $display("******@%0tns %s noses : %0d ****",$time, name, animal_obj.noses);
endtask
task automatic animal_assign_modified(ref [76:0] data_in, ref animal animal_obj);
  animal_obj.height  =  data_in[76 -: 32];
  animal_obj.weight  =  data_in[76-32 -: 32];
  animal_obj.legs    =  data_in[76-32-32 -: 8];
  animal_obj.hands   =  data_in[76-32-32-8 -: 2];
  animal_obj.eyes    =  data_in[76-32-32-8-2 -: 2];
  animal_obj.noses   =  data_in[0];
  data_in = '0; endtask initial begin data_in = {32'd132, 32'd200, 8'd2, 2'd2, 2'd2, 1'd1}; animal_assign(data_in, duck); name = "duck"; animal_display(name, duck) data_in = {32'd132, 32'd100, 8'd2, 2'd0, 2'd2, 1'd1};
  animal_assign(data_in, dog);
  name = "dog";
  animal_display(name, dog);
  animal_assign_modified(data_in, dog);
  animal_display(name, dog);
  $display("******After data_in modified by dog structure");
  animal_assign(data_in, duck);
  name = "duck";
  animal_display(name, duck);
end 
endmodule 

rslt.log

******@0ns duck unpacked value automatic animal_assign&animal_display******
******@0ns duck height   :  132 ****
******@0ns duck weight   :  200 ****
******@0ns duck legs     :  2 ****
******@0ns duck hands    :  2 ****
******@0ns duck eyes     :  2 ****
******@0ns duck noses    :  1 ****
******@0ns dog unpacked value automatic animal_assign&animal_display******
******@0ns dog height   :  132 ****
******@0ns dog weight   :  100 ****
******@0ns dog legs     :  2 ****
******@0ns dog hands    :  0 ****
******@0ns dog eyes     :  2 ****
******@0ns dog noses    :  1 ****
******@0ns dog unpacked value automatic animal_assign&animal_display******
******@0ns dog height   :  132 ****
******@0ns dog weight   :  100 ****
******@0ns dog legs     :  2 ****
******@0ns dog hands    :  0 ****
******@0ns dog eyes     :  2 ****
******@0ns dog noses    :  1 ****
******After data_in modified by dog structure
******@0ns duck unpacked value automatic animal_assign&animal_display******
******@0ns duck height   :  0 ****
******@0ns duck weight   :  0 ****
******@0ns duck legs     :  0 ****
******@0ns duck hands    :  0 ****
******@0ns duck eyes     :  0 ****
******@0ns duck noses    :  0 ****
  • You can see the changes ref Quoted variables , Then call the variable , This variable is the changed value .
  • ref It's easy to make mistakes , It is not recommended for actual use .

Reference resources

原网站

版权声明
本文为[luoganttcc]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/188/202207070443428340.html