数据类型
- 动态数组: 声明时不需要指定个数
- 关联数组区别于动态数组的地方: 索引方式;
关联数组:
integer as_mem [integer];
- queue name[$]
Each element in a queue is identified by an ordinal number that represents its position within the queue, with 0 representing the first, and $ representing the last.
- 0 : Used to access first element of queue
- $ : Used to access last element of queue
- {} : Used along with first and last operator to add/delete elements
- queue ::
并行
fork ... join
fork
begin
...
end
begin//每个begin end内的代码串行;各个begin之间代码并行
...
end
join
fork
task //task or function 并行
function
join
join
等所有分支结束再开始执行后续代码
-
join any
任意一个分支结束即开始执行后续代码,后续代码可能也fork中的未完成的分支的代码并行执行 -
join none
开始执行各个分支之后即开始执行后续代码
函数
- task/function
- task 可以加延迟或比如说等一个上升沿
- function 不能延迟
- task 没有返回值,function可以由返回值
task doInit (input bit[3:0] count, delay);
automatic reg[7:0] a;
if(count > 5)begin
$display("@%g Returning from task",$time);
return
end
#(delay)$display("@%g Value passed is %d",$time, count); //task中插入延迟
endtask
-
task/funciton port
- input : copy value in at beginning
- output : copy value out at end
- inout : copy in at beginning and out at end
- ref : pass reference
-
Argument Passing
- Pass by value
- Pass by reference
- Pass by name
- Pass by position
- default values
- Optional arguments.
-
ref 相当于指针;
进程间通信
- mailbox 可以传递参数,像fifo
- semaphores 如同令牌/许可证 put(3) 可以 get(1),也可以get(3)
这里的值并不是判断put/get的值相等才能执行;
- new()
- get()
- put()
包定义
- pakage相等于module,c的函数; 里边的变量在pakage内部为局部变量;作用是限定变量的scope;
编译空间中存放不在任何一个pakage的代码 , 编译空间相当于一个特殊的pakage
class
- class 如同struct,可以嵌套;
int a; //int 类型,a为int类型的变量
class_name c_o; //class_name class类型,c_o 是一个object
//c_o是一个handle 没有分配内存空间;
- 类成员变量static,所有对象共享一个属性,相当于全局变量,方便参数传递;
- 类的方法也可以是静态的,所有的类都可以直接调用其他类的静态方法,即使调用没有初始化的对象也是合法的,但是静态方法不能调用非静态成员,如果调用会产生编译错误。静态方法不能为虚方法。另外需要注意区分的是静态方法和一般方法但是变量为静态生命周期。
- this只能用在非静态的成员函数中
指针复制/浅拷贝/深拷贝
-
指针复制
class_name a; class_name b; a=new(); b=a; //b,a指向同一个内存空间
-
浅拷贝
-
深拷贝
代码需要自己写
浅拷贝是指源对象与拷贝对象共用一份实体,仅仅是引用的变量不同(名称不同)。对其中任何一个对象的改动都会影响另外一个对象。举个例子,一个人一开始叫张三,后来改名叫李四了,可是还是同一个人,不管是张三缺胳膊少腿还是李四缺胳膊少腿,都是这个人倒霉。
深拷贝是指源对象与拷贝对象互相独立,其中任何一个对象的改动都不会对另外一个对象造成影响。举个例子,一个人名叫张三,后来用他克隆(假设法律允许)了另外一个人,叫李四,不管是张三缺胳膊少腿还是李四缺胳膊少腿都不会影响另外一个人。
class baseA ;
integer j = 5;
endclass
class B ;
integer i = 1;
baseA a = new;
endclass
module test();
//xtndA xtnd1;
baseA base2, base3;
int test;
initial begin
B b1 = new; // Create an object of class B
B b2 = new b1; // Create an object that is a copy of b1
b2.i = 10; // i is changed in b2, but not in b1
$display("b1.i = %0d",b1.i);
b2.a.j = 50; // change a.j, shared by both b1 and b2
$display("b1.a.j = %0d",b1.a.j);
end
endmodule
继承
- 把通用的代码放到父类
- 继承重载:当子类的方法需要和父类不同时使用;
super
- 当在子类中需要对父类的属性进行操作,或者调用父类的方法可以使用super指针直接指向该成员
虚函数
- 父类中需要多态的方法必须被声明成virtual以便被覆盖
class BasePacket;
int A = 1;
int B = 2;
function void printA;
$display("BasePacket::A is %0d", A);
endfunction : printA
virtual function void printB;
$display("BasePacket::B is %0d", B);
endfunction : printB
endclass : BasePacket
class My_Packet extends BasePacket;
int A = 3;
int B = 4;
function void printA;
$display("My_Packet::A is %0d", A);
endfunction: printA
virtual function void printB;
$display("My_Packet::B is %0d", B);
endfunction : printB
endclass : My_Packet
module test();
BasePacket P1 = new;
My_Packet P2 = new;
initial begin
P1.printA;
P1.printB;
P1 = P2;
P1.printA;
P1.printB; // 此处调用子类函数
P2.printA;
P2.printB;
end
endmodule
数据的隐藏与封装
- 一个local成员只能被当前类中的方法访问,即使是其子类也无法访问local成员。
- protected成员和local成员什么相似,只是其对于子类是可见的。
类的常量
- 在SystemVerilog中也可以通过在变量前面加上const来声明一个只读属性;
- 全局常量,在声明变量时就初始化了初值,除了这里以外的任何地方都不允许再更该其值。
- 实例常量, 实例常量在声明的时候只有const关键字而没有初值,只在相应的构造函数中将其初始化。
- 全局常量也可以被声明为static,对所有的对象来说是共用一个这样的变量的,而实例常量却不能声明为static,因为静态常量不能在构造函数中赋值。
多态
- 注意多态的实现需要四个条件:有继承,有重写,父类指针指向子类对象,还有有父类函数的virtual。
- SV所提供的机制被称为单继承,也就是说,每一个子类都由一个单一的父类继承而来,父类的方法可以被覆盖或隐藏。不支持同一类域中同名不同参的方法重载。父类中需要多态的方法必须被声明成virtual以便被覆盖。普通类的virtual方法必须被具体实现,virtual类的方法可以没有具体的实现。virtual类不能被实例,只能被继承。super关键字在一个子类的内部使用,可以用来引用其父类的成员。
封装
为了减少代码之间的依赖关系
网友评论