基础
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| class sv_class; int x; static byte no_pkts_created; task set(int i); x = i; endtask function int get(); return x; endfunction
static function get_pkt_ctr(); $display("ctr=%d", no_pkts_created); endfunction
function new(); this.x = x; $display("pkt_id: %d", no_pkts_created); no_pkts_created++; endfunction
function sv_class copy(); copy = new(); copy.x = this.x; return copy; endfunction endclass
module class_tb;
sv_class cls, cls2;
initial begin cls = new(1); cls2 = new cls; sv_class::get_pkt_ctr(); end endmodule
|
浅复制不会复制类中的类(内部类),而是共享同一片存储空间
和interface类似,class也可以使用参数化设计
1 2 3 4 5 6 7 8 9 10 11
| class packet #(parameter int ADDR_WIDTH = 32,DATA_WIDTH = 32); bit [ADDR_WIDTH-1:0] address; bit [DATA_WIDTH-1:0] data ; function new(); address = 10; data = 20; endfunction endclass
|
继承与多态
在sv的class中,可以使用extends继承父类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| class parent_class; bit [31:0] addr;
virtual function void display(); $display("parent"); endfunction endclass class child_class extends parent_class; bit [31:0] data;
function void display(); $display("child"); endfunction endclass module inheritence; initial begin child_class c = new(); c.addr = 10; c.data = 20; $display("Value of addr = %0d data = %0d",c.addr,c.data);
parent_class p = c; p.display(); end endmodule
|
权限控制:
- public: 默认值,不需要写public,使用super关键字可以访问父类成员
- local:只有自己可以访问,子类无法访问
- protected: 只有自己和子类可以访问
抽象类
- 抽象类无法实例化,只能被继承
- 抽象类可以包含只有一个原型的函数(纯虚函数)
1 2 3 4 5
| virtual class BasePackt; int id; pure virtual function int send(bit[31:0] data); endclass
|
constraints
constraints对成员变量的随机化进行一些约束,确保他们的随机值在这个范围之内
语法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| rand byte data;
constraint data_cons{ data > 0; data <5; } ------------------------ constraint data_cons{ data inside {[0:3],[8:10]}; } ------------------------ int array = '{1,2,2,3,3,3,4,4,4,4} constrain data_c { data inside array; } -------------------------- constraint data_cons { data dist {0, 2, [5: 10]}; } --------------------------- constraint data_cons{ data dist {0:=10,[1:3]:=45}; } ----------------------------
constraint data_cons{ data dist {0:/10,[1:3]:/45}; } -----------------------------
constraint data_cons{ (data_flag > 2) -> data inside {[1:3]}; (data_flag <= 2) -> data inside {[4:6]}; } 等同于 constraint data_cons{ if(data_flag>2) data inside {[1:3]}; else data inside {[4:6]}; } ---------------------------------- 数组的约束 rand byte pload[]; constraint pload_cons { foreach(pload[i]) { pload[i] inside {[1:255]}; } pload.sum < 1024; pload.size() inside {[1:8]}; }
|
约束的开关:
- 关闭某一个约束:
module_name.constraint_name.constraint_mode(0)
- 关闭一个模块内所有约束:
module_name.constraint_mode(0)
约束的重载:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| class my_transaction extends uvm_sequence_item;
rand bit crc_err; rand bit sfd_err; constraint crc_err_cons{ crc_err == 1'b0; } constraint sfd_err_cons{ sfd_err == 1'b0; }
`uvm_object_utils_begin(my_transaction) `uvm_field_int(sfd_err, UVM_ALL_ON | UVM_NOPACK) `uvm_field_int(pre_err, UVM_ALL_ON | UVM_NOPACK) `uvm_object_utils_end
function new(string name = "my_transaction"); super.new(); endfunction
endclass
class new_transaction extends my_transaction; `uvm_object_utils(new_transaction) function new(string name= "new_transaction"); super.new(name); endfunction
constraint crc_err_cons{ crc_err dist {0 := 2, 1 := 1}; } endclass
|