Title

SystemVerilog -- 3.10 SystemVerilog Functions

SystemVerilog Functions

SystemVerilog函数具有与Verilog中的function相同的特征。

Functions

a的主要用途是返回一个可在表达式中使用且不能消耗模拟时间的值。function

  • function不能具有时间控制语句,如@ # fork join wait
  • function无法启动task,因为允许task消耗模拟时间。

ANSI-C style declaration

module tb;
  // There are two ways to call the function:
  initial begin
    // 1. Call function and assign value to a variable, and then use variable
    int s = sum(3, 4);
    $display ("sum(3, 4) = %0d", s);

    // 2. Call function and directly use value returned
    $display ("sum(5, 9) = %0d", sum(5, 9));
    $display ("mul(3, 1) = %0d", mul(3, 1));
  end

  // This function returns value of type "byte", and accepts two arguments "x" and "y". A return variable of the same name as function is implicitly declared and hence "sum" can be directly assigned without having to declare a separate return variable
  function byte sum (int x, int y);
    sum = x + y;
  endfunction

  // Instead of assigning to "mul", the computed value can be returned using "return" keyword
  function byte mul (int x, y);
    return x * y;
  endfunction
endmodule

模拟日志

ncsim> run
sum(3,4) = 7
sum(5,9) = 14
mul(3,1) = 3
ncsim: *W,RNQUIE: Simulation is complete.

Using declarations and directions

尽管后来在Verilog中引入了ANSI-C样式的声明,但端口方向的旧式声明仍然有效。SystemVerilog function可以将参数声明为输入和输出端口,如以下示例所示。

module tb;
  initial begin
     int res, s;
     s = sum(5, 9);
     $display ("s = %0d", sum(5, 9));
     $display ("sum(5, 9) = %0d", sum(5, 9));
     $display ("mul(3, 1) = %0d", mul(3, 1, res));
     $display ("res = %0d", res);
  end

  // Function has an 8-bit return value and accepts two inputs and provides the result through its output port and return val
  function bit [7:0] sum;
    input int x, y;
    output sum;
    sum = x + y;
  endfunction

  // Same as above but ports are given inline
  function byte mul (input int x, y, output int res);
    res = x * y + 1;
    return x * y
  endfunction
endmodule

模拟日志

ncsim> run
s = 14
sum(5,9) = 14
mul(3,1) = 3
res = 4
ncsim: *W,RNQUIE: Simulation is complete.

How to pass arguments by value ?

传递值是将参数传递给子例程的默认机制。每个参数都复制到子例程区域中,并且在子例程区域中对此局部变量所做的任何更改在子例程之外都不可见。

module tb;
  initial begin
    int a, res;
    
    // 1. Let's pick a random value from 1 to 10 and assign to "a"
    a = $urandom_range(1, 10);
    // Function is called with "" which is the default mode
    res = fn(a);

    // Even if value of a is changed inside the function, it is not reflected here
    $display ("After calling fn: a=%0d res=%0d", a, res);
  end

  // This function accepts arguments in "pass by value" mode and hence copies whatever arguments it gets into this local variable called "a".
  function int fn (int a);
    // Any change to this local variable is not reflected in the main variable declared above within the initial block
    a = a + 5;

    // Return some computed value
    return a * 10;
  endfunction
endmodule

请注意,从下面显示的日志中,即使为function中定义的局部变量分配了不同的值,块内的a值也不会更改。initial

模拟日志

ncsim> run
Before calling fn: a=2 res=0
After calling fn: a=2 res=70
ncsim: *W,RNQUIE: Simulation is complete.

How to pass arguments by reference ?

通过引用传递的参数不会复制到子例程区域,而是将对原始参数的引用传递给子例程。参数声明前面是关键字。对子例程内变量所做的任何更改都将反映在子例程外的原始变量中。ref

// Use "ref" to make this function accept arguments by reference
// Also make the function automatic
function automatic int fn (ref int a);
  // Any change to this local variable will be reflected in the main variable declared within the initial block
  a = a + 5;
  // Return some computed value
  return a * 10;
endfunction
Its illegal to use argument passing by reference for subroutines with a lifetime of `static`

模拟日志

ncsim> run
Before calling fn: a=2 res=0
After calling fn: a=7 res=70
ncsim: *W,RNQUIE: Simulation is complete.

posted on 2024-05-06 21:45  松—松  阅读(122)  评论(0编辑  收藏  举报

导航