SV-grammar1

组合型(packed)数组

组合型(packed)数组初始化时,同向量初始化一致

非组合型(unpacked)数组

  • 非组合型(unpacked)数组初始化时,则需要通过’{ }来对数组的每一个维度进行赋值。
  •  对于非组合型数组,在发生数组间拷贝时,则要求左右两侧操作数的维度和大小必须严格一致。

数组系统函数

    $dimensions(array_name)//用来返回数组的维度。

    $left(array_name,dimension)//返回指定维度的最左索引值(msb)
    $right(array_name,dimension)
    $low(array_name,dimension)
    $high(array_name,dimension)
    $size(array_name,dimension)//可以返回指定维度的尺寸大小。
    $increment(array_name,dimension)//如果指定维度的最左索引值大于或等于最右索引值,那么返回1,否则返回-1。
    $bits(expression)//可以用来返回数组存储的比特数目。

foreach循环结构特点: 

    • foreach循环结构中的变量无需声明。
    • foreach循环结构中的变量是只读的,其作用域只在此循环结构中。

————————————————

队列

  • SV引入了队列类型,它结合了数组和链表。
  • 可以在队列的任何位置添加或者删除数据成员。
  • 可以通过索引来访问队列的任何一个成员。

通过[$]来声明队列,队列的索引值从0到$。

//添加或者移除并且获得数据成员
push_back(val)//在队列后面插入
push_front(val)//在队列前面插入
pop_back()//删除后面的元素
pop_front()//删除前面的元素
insert (val, pos)//在指定位置插入数据成员。
delete()//删除所有数据成员。

关联数组:可以用来存放散列的数据成员

三种数组的公共方法

缩减方法

        基本的数组缩减方法是把一个数组缩减成一个值。
        最常用的缩减方法是sum,它对数组中的所有元素求和。

byte b [$]={2,3,4,5};
int w;
w=b.sum () ; //14=2+3+4+5
w=b.product() ; //120=2*3*4*5
w=b.and() ; //0000_0000=2 & 3 & 4 & 5

product(积)
and(与)
or(或)
xor(异或)。

定位方法

int f[6]='{1,6,2,6,8,6}; //定长数组
int d[]='{2,4,6,8,10}; //动态数组
int q[$}={1,3,5,7}, //队列
tq[$]; //保存结果的临时队列
tq=q.min() ; //{1}
tq=d.max (); //{10}
tq=f.unique(); //{1,6,2,8}

数组的搜索

int d[]=’{9,1,8,3,4,4} , tq[$];//找出所有大于3的元素
tq = d.find with (item >3) ;// {9,8,4,4}
//等效代码
ta.delete() ;
foreach (d[i])
if(d[i]>3)
tq. push_back(d[i]);

tq = d.find_index with (item > 3);// {0,2,4,5}
tq = d.find_first with (item > 99);//{}–没有找到
tq = d.find_first_index with (item==8);//{2} d[2]=8
ta = d.find_last with (item==4);//{4]
tq = d.find_last_index with (item==4); // {5} d[5]=4

排序方法

int d[]='{9,1,8,3,4,4};
d.reverse(); //'{4,4,3,8,1,9}; 逆序
d.sort(); //'{1,3,4,4,8,9}; 从小到大
d.rsort(); //{9,8,4,4,3,1};从大到小
d.shuffle(); //'{9,4,3,8,1,4}乱序排列

————————————————

接口与模块的定义有许多相似之处 :

  • 接口的定义同模块定义类似。
  • 接口也可以有端口,例如外部接入的时钟或者复位信号。
  • 接口内部可以声明所有的变量或者线网类型。

接口和模块的区别:

  • 接口不同于模块的地方在于,接口不允许包含设计层次,即接口无法例化模块,但是接口可以例化接口。
  • 可以在接口声明modport来约束不同模块连接时的信号方向。
  • 模块的端口如果声明为input、output或者inout,那么在例化时可以不连接。

接口特点:

  • 接口提高了建模级别,接口对于设计复用非常有利。
  • 接口减少了模块之间错误连接的可能性。
  • 如果要添加新的信号,只需要在接口中声明,而不必在模块中声明。
  • 由于接口将有关信号都集合在一起,因此在使用这些信号时需要添加接口实例名。
  • 一种接口往往会将有关的信号集合在一起,对于拥有多组不相关信号的设计而言,它需要有多个接口才能完成与其它模块的连接。

————————————————

modport

  • 接口中的变量或者线网信号,对于连接到该接口的不同模块则可能具备着不同的连接方向。
  • 接口引入了modport来作为moduleport的缩写,表示不同的模块看到同一组信号时的视角(连接方向)。
  • 在接口中声明modport,需要指明modport中各个信号的方向。

当一个模块在例化时,可以选择连接到interface端口中具体的某一个modport。 这种方式可以降低方向连接错误的可能,进而避免信号多驱动的情况。

————————————————

SV中字符串的特点:

  • 字符串类型变量的存储单元为byte类型( 8位二值逻辑)。
  • 字符串类型变量长度为N时,其字符成员索引值为从0到N-1
  • 不同于C语言,字符串结尾没有空字符“\0”
  • 字符串的内存是动态分配的,用户无需担心内存空间管理。

————————————————

 字符串内建方法:

str.len()//返回字符串的长度。
str.putc(i, c)//将第i个字符替换为字符c,等同于str[i]=c。
str.getc(i)//返回第i个字符。
str.substr(i,j)//将从第i个字符到第j个字符的字符串返回。
str. {atoi(), atohex(), atooct, atobin}//将字符串转变为十进制、十六进制、八进制或者二进制数据。











module
data_type; // TODO-2: distinguish bit and logic initial begin: bit_vs_logic bit v1; logic v2; wait(b_bit_vs_logic == 1); $display("bit_vs_logic process block started"); v2 = 'bx; $display("logic variable v2 = %d", v2); v1 = v2; $display("bit variable v1 = %b", v1); v2 = 'bz; $display("logic variable v2 = %b", v2); v1 = v2; $display("bit variable v1 = %b", v1);
//不管z和x,bit都是0
end // TODO-3: enum type initial begin: enum_type typedef enum {IDLE, START, PROC, END} state_t; state_t st1, st2; wait(b_enum_type == 1); $display("enum_type process block started"); st1 = IDLE; $display("st1 value = %0d (int)", st1); $display("st1 value = %s (string)", st1); // implicit conversion $display("st1 value = %s (string)", st1.name()); st2 = state_t'(1); //注意此处赋值 $display("st1 value = %0d (int)", st2); $display("st1 value = %s (string)", st2.name()); end // TODO-4: struct type initial begin: struct_type typedef struct { //要试一下packet bit[7:0] addr; bit[31:0] data; bit is_write; int id; } trans_t; trans_t t1, t2, t3; wait(b_struct_type == 1); $display("struct_type process block started"); t1 = '{'h10, 'h1122_3344, 'b1, 'h1000}; //赋值 $display("t1 data content is %p", t1); // 结构体的输出%p,输出的是整形 t2.addr = 'h20; t2.data = 'h5566_7788; t2.is_write = 'b0; t2.id = 'h2000; $display("t2 data content is %p", t2); t3 = t2; t3.data = 'h99AA_BBCC; t3.id = 'h3000; $display("t3 data content is %p", t3); $display("t2 data content is %p", t2); end endmodule

 

// TODO-1 understand how to formulate a new string
initial begin: string_format
  string s1, s2, s3, s4, s5;
  wait(b_string_format == 1);$display("string_format process block started");
  s1 = "Welcome";
  s2 = "www.rockeric.com";

  s3 = {s1, " to ", s2}; // concatenation operator '{...}'
  $display("s3 content: %s", s3);

  s4 = $sformatf("%s to %s", s1, s2); // system format function
  $display("s4 content: %s", s4);
  s5 = $psprintf("%s to %s", s1, s2); // system format function 和{},sformatef一样的
  $display("s5 content: %s", s5);
end

// TODO-2  understand how s3 is composed with s1 and s2
initial begin: string_builtin_function
  string s1, s2, s3;
  int i1;
  wait(b_string_builtin_function == 1); $display("string_builtin_function process block started");
  s1 = "RockerIC is established in ";
  i1 = 2015;
  s2.itoa(i1); // integer converted to string “2015”
  $display("s2 = %s", s2);
  s3 = {s1.len()+s2.len(){" "}}; // 开辟空间,不开后面不能加入进来try to comment this line and check the result
  $display("s3 content: [%s]", s3);
  for(int i=0; i<s1.len()+s2.len(); i++) begin     //拼接
    s3[i] = i < s1.len() ? s1[i] : s2[i-s1.len()]; 
    //  s3[i] = i < s1.len() ? {s3,s1[i]} : {s3,s2[i-s1.len()]}; //如果不开辟空间,可以拼接
  end
  $display("s3 content: %s", s3);
end

 

posted @ 2023-02-04 21:58  天下大任望君莫辞  阅读(215)  评论(0)    收藏  举报