SystemVerilog 带输出的task

 从task或function中返回数组的方法。

 1、task 的定义,输出定义为数组。

1 typedef   bit [7:0]     bit8;
2 task genRndPkt(input int length, output bit8 pkt[]);
3         pkt = new[length];
4         //动态数组需要new;
5         for (int i = 0; i < length; i++) begin
6              pkt[i] = $urandom_range(0, 255);
7         end
8   endtask

     这种代码适合从存储器中根据地址和长度信息,抽取数据到动态数组中;

2、通过函数名返回数组。

1 typedef  int  fixed_array5[5];
2 fixed_array5  f5;
3 function  fixed_array5 init(int  start);
4     foreach(init[i])
5         init[i] = i+start;
6 endfunction

在sv绿皮书的59页,通过定义数组类型,然后在函数返回值得类型声明为该数组类型,即可以返回数组,用于程序右值。

这种方式不常见而且数组做右值时,需要数组copy,效率低下。但是这种思想还是可以的。

这种方式的理解上可以认为函数名即是函数返回值得首地址,所以可以在函数体中直接使用函数名做数组使用。

 3、数组pack、unpack操作。

1  typedef   bit [7:0]     bit8;
2  typedef   bit [31:0]    bit32;
3  typedef   bit [63:0]    bit64;
4  typedef   bit [127:0]   bit128;
5  typedef   bit8          bit8_16[16]; //这种使用方法很难理解
6 
7  function bit128 unpack2pack(bit8_16 dataBlock);
8      for (int i = 0; i < 16; i++) unpack2pack[8*i+:8] = dataBlock[i];
9  endfunction
1   function bit8_16 pack2unpack(bit128 dataBlock);
2       for (int i = 0; i < 16; i++) pack2unpack[i] = dataBlock[8*i+:8];
3   endfunction

unpack2pack 是bit128 类型的,pack2unpack 是bit8_16[16] 类型的,函数体中可以直接用函数名称做数组使用。

unpack2pack[8*i+:8] 表示unpack2pack[8*i +8 : 8*i],但是由于systemverilog不支持索引中上下界都是变量,所以使用这种方式,切经常使用这种方式处理数据。 

 4、把数组作为ref参数传递给函数。

1 function  void  print_checksum(const  ref  bit[31:0] a[])
2     bit  [31:0]  checksum = 0;
3     for (int i=0;i<a.size();i++)
4         checksum ^=a[i];
5     $display("checksum is %0d", checksum);
6 endfunction

这种方式最有效率,应该尽可能的用ref来传递数组。

 

posted on 2016-12-09 18:58  hematologist  阅读(1270)  评论(0编辑  收藏  举报

导航