SV中的数据类型
Verilog-1995中规定的数据类型有:变量(reg), 线⽹(wire), 32位有符号数(integer), 64位⽆符号数(time), 浮点数(real)。
SV扩展了reg类型为logic,除了reg类型的功能外,可以⽤在连续赋值,门单元和模块所驱动。但是不能⽤在双向总线建模,不能有多点驱动。
其他数据类型:⽆符号双状态  bit,
有符号双状态32位  int,
有符号双状态8位    byte,                            //可以⽤内置函数  $isunknown
有符号四状态32位  integer,
⽆符号四状态64位  time,
有符号双状态浮点64位    real.
$isunknown()----在操作数中存在X、Z时,返回1。
$bits(expression)----返回expression占的位宽。
对于四状态类型的数据,缺省值为X,双状态类型的数据,缺省值是0.
很多SV仿真器在存放数据元素的时候都是使⽤32bit的字边界。所以byte、shortint、int都是存放在⼀个字中,longint则存放在两个字中。
对于四状态的数据,SV仿真器通常使⽤两个连续的字或更多的连续的双字来存放它们的值,所以四状态的变量会消耗双倍的空间。
连续的双字,⼀个字存放数据的0/1值,另⼀个字存放x/z状态。
foreach可以进⾏多维数据的递归调⽤,foreach(A[i,j])
定宽数组:
(pack)合并数组:将数组⼤⼩的定义放在等式左边            bit [3:0][7:0] bytes;          //4个字节组成⼀个字,储存空间⼀个字。
(unpack)⾮合并数组:将数组⼤⼩的定义放在等式右边        bit [7:0] bytes [4];            //4个字节,这个仍是合并数组,但是4个存储空间不连续,这是⾮合并数组
    unpacked array会被认为是⼀个vector,packed array会被认为是⼀个scalar。
    unpacked array的声明有两种⽅式:
      1. int array [0:7][0:31];  array delaration using ranges
      2. int array [8][32];        array delaration using size
当需要和标量进⾏数据交换时,使⽤合并数组很⽅便,⽽且@操作符的数据只能是标量和合并数组。所以推荐使⽤合并数组,还节省空间。
bit [3:0][7:0] barray[3];  //当使⽤@操作符时,只能使⽤@(barray[0] or barray[1] or barray[2])不能使⽤整个barray。
bit [31:0] src[5] = `{0,1,2,3,4},  dst[5] = `{5,4,3,2,1};                      //数组的直接初始化
if(src == dst)  $display("src==dst");                                                    //数组可以直接进⾏整体的⽐较
dst = src; src[0] = 5;                                                                          //数组可以直接进⾏整体的赋值和单个的赋值。
数组的系统函数sum, min, max, unique, with, reverse, sort, resort, shuffle
int q[4] = ‘{1,3,5,7}, tq[10];
tq = q.min();                  //{1}
tq = q.max();                  //{7}
tq = q.unique();                //{1,3,5,7}
tq = q.find with (item > 3);          //{5,7}所有⼤于3的元素,item这⾥是缺省值,也可以显式的指出。
tq = q.find with(x) (x > 3);
tq = q.find_index with (item > 3);    //{2,3}所有⼤于3的元素的index。
tq = q.find_first with (item > 99);    //返回第⼀个⼤于99的元素,{}⽆
tq = q.find_first_index with (item > 6);  //{3}
tq = q.sum with (item > 6);            //{7}
tq = q.reverse();                            //{7,5,3,1}
tq = q.sort();                                  //{1,3,5,7}
tq = q.resort();                              //{7,5,3,1}
tq = q.shuffle();                              //{3,5,1,7} 再随机化⼀个
动态数组:声明时使⽤空[],位宽在编译时不指出,在运⾏时动态分配。使⽤前必须⽤new[]来初始化并分配空间。系统函数size,delete              int dyn[];
dyn = new[5];
dyn = new[20](dyn);  //分配20个空间,并复制原来的5位数据,放在新的20个空间的前五个。
dyn.delete;        //删除整个数组
$size(dyn);        //动态数组的个数
队列:在SV中结合了链表和数组的优点,集插⼊与查询的优点于⼀体。声明时使⽤美元符号[$],系统函数insert, delete, push_front, push_back, pop_front,
pop_back。推荐后边的pop, push操作。
int q[$] = {0,2,5};        //初始化,不需要‘
q.insert(1,1);          //{0,1,2,5},在第⼀个元素之前,插⼊1
q.delete(1);            //删除第⼀个元素,{0,2,5}
q.push_front(6);      //{6,0,2,5}在队列前插⼊6
字符串截取前四位q.push_back(8);      //{6,0,2,5,8}在队列后插⼊8
j = q.pop_front;      //pop出队列的第⼀个元素,j=6 q={0,2,5,8}
j = q.pop_back;      //pop出队列的最后⼀个元素,j=8 q={0,2,5}
关联数组:SV采⽤树或哈希表的形式来保存,声明时在⽅括号中放置数据类型,如[int], [bit[8:0]]。
bit [63:0] assoc[bit[63:0]], idx =1;
repeat(64)  begin
assoc[idx] = idx;      idx = idx<<1;          //赋值
end
foreach (assoc[i])    $display ("assoc[%h] =%h", i , assoc[i]);      //⽤foreach来遍历
if(assoc.first(idx))    begin
do  $display("assoc[h] = %h",idx,assoc[idx]);      //do...while遍历,first/next
(idx));
end
ists(idx) )                            //exists 系统函数
    num()函数和size(),返回哈希的个数,
枚举类型:声明包含⼀个常量名称列表以及⼀个或多个变量。系统函数name(),由变量值返回字符串。first(), last(), next(), prev(),
typedef enum {INIT, DECODE=2, IDLE} fsmtype_e;            //INIT的值为0,IDLE的值为2
typedef enum {FIRST=1, SECOND, THILD} ordinal_e;    ordinal_e  position;  //枚举类型默认会存储为int类型,缺省值为0,所以FIRST只能是0
typedef enum {FIRST=0, SECOND, THILD} ordinal_e;  right
color = color.first;        do    begin
$display("Color = %d/%s",color,color.name);
color = ;
end  while(color != color.first);      //枚举遍历
  num(),返回enum中的个数。
字符串:string类型可以⽤来保存字符串,单个字符串是byte类型,采⽤动态分配的储存⽅式,长度为N的字符串,元素编号0-N-1,结尾不带'\0'。
系统函数getc(N), tolower(), putc(N,C), subtr(M,N), len(), toupper()
string s = "IEEE";
$(0));          //返回第零个字符 'I'
$lower() );          //显⽰ 'ieee'
s.putc(s.len()-1,"-" );          //变为 'IEEE-'
s = {s, "P1800"};                //变为  'ieee-P1800'
typedef关键字:  typedef  reg[OPSIZE-1:0]opreg_t;                  opreg_t  op_a,op_b;
typedef  int  fixed_arrays5[5];                        fixed_arrays5    f5;  //5个数据的数组
struct关键字:    struct  {bit [7:0] r,g,b;}  pixel;                      只是声明⼀个pixel变量;
typedef  struct packed {bit[7:0] r,g,b;}  pixel_p_s;          pixel_p_s  my_pixel;    //packed的⽅式,表⽰合并结构,紧凑的存储⽅式
数据类型转换:静态转换 real j;  j=int '(10.1 - 0.1);                        //强制转换为整型。
流操作符:          >>把数据从左⾄右变成流,<<;把数据从右往左变成流。
bit [7:0] j[4] = '{8'ha, 8'hb, 8'hc, 8'hd};  int h;
h = {>>{j}};                //把数据0a0b0c0d打包成整型。
h = {<<{j}};                //把数据倒序b030d050打包成整型。
h = {<<byte{j}};          //0d0c0b0a字节倒序打包成整型。
{>>h} = j;                    //把j分散到四个字节变量中。
  在流操作符中,还可以直接使⽤with,来动态的显⽰参与运算的数组的区间;
    {<< byte {header, len, payload with [0+:len],crc}} = stream;
    区间的表⽰可以是[expression: expression],[expression+: expression],[expression-: expression]
SV中可以设置参数化的module/class/interface/mailbox
module ma #(parameter p1 = 1, parameter type p2 = shortint)
(input logic [p1:0] i, output logic [p1:0] o); ..............
endmodule
interface quit_timer_checker #(parameter min_quiet = 0,
parameter max_quiet = 0)
(input logic clk, reset_n, [1:0]en);
endinterface
class vector #(size == 1);
logic [size-1:0] v;
endclass
参数化的打印:sformatf(int_type, "string");
       psprintf("string", type);
set membership operator,直接判断某个expression是否在⼀个list中;  if(a inside {b,c}) begin
  end
  if(ex inside {array}) begin  直接⽤在数组判断中
  end
part select操作符:
  +:a_vect[ o+: 8]  = a_vect[0:7]
  -: a_vect[15-:8] = a_vect[8:15]
{},可以拼接字符串,和数值。
n{var},表⽰n个var拼接。
Assignment pattern:'{}来直接赋值。
  1) index:value,  integer i = ‘{31:1, 23:1,15::1,8:1,default:0 };          int a3[] = '{1, 2, 3}
  2) type:value, struct { int a;  time b; }  key[2];
         key = '{ '{a:1, b:2ns}, '{int:5, time:$time} };
  3) default:value,  int a[3] = '{default:1};

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。