建设银行企业网站访问不了,网站制作和美工,软文广告营销,app费用文章目录 SV入门练习基本数据类型字符串类型数组类型接口的定义与例化类的封装类的继承package的使用随机约束线程的同步线程的控制虚方法方法#xff08;任务与函数#xff09;SV用于设计 参考资料 SV入门练习
基本数据类型
有符号无符号、四状态双状态、枚举类型、结构体… 文章目录 SV入门练习基本数据类型字符串类型数组类型接口的定义与例化类的封装类的继承package的使用随机约束线程的同步线程的控制虚方法方法任务与函数SV用于设计 参考资料 SV入门练习
基本数据类型
有符号无符号、四状态双状态、枚举类型、结构体 module data_bytebit b_signed_vs_unsigned 1;
bit b_bit_vs_logic 1;
bit b_enum_type 1;
bit b_struct_type 1;// TODO-1: distinguish signed and unsigned type
initial begin: signed_vs_unsignedbyte b0;bite[7:0] b1;wait(b_signed_vs_unsigned 1);$display(signed_vs_unsigned process block started);b0 b1000_0000;$display(byte variable b0 %d, b0);b1 b0;$display(bit vector variable b1 %d, b1)
end// TODO-2: distinguish bit and logic
initial initial begin: bit_vs_logicbit v1;logic v2;wait(b_bit_vs_logic 1); $display(bit_vs_logic process block started);v2 b1;$display(logic variable v2 %d, v2);v1 v2;$display(bit variable v1 %d, v1);v2 b0;$display(logic variable v2 %d, v2);v1 v2;$display(bit variable v1 %d, v1);v2 bx;$display(logic variable v2 %d, v2);v1 v2;$display(bit variable v1 %d, v1);v2 bz;$display(logic variable v2 %d, v2);v1 v2;$display(bit variable v1 %d, v1);
end// TODO-3: enum type
initial begin: enum_typetypedef 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_typetypedef struct {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);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);
endendmodule
字符串类型
构建字符串和字符串拼接 一般常用$sformatf函数
module string_type;bit b_string_format 1;
bit b_string_builtin_function 1;// TODO-1 understand how to formulate a new string
initial begin: string_formatstring s1, s2, s3, s4;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);
end// TODO-2 understand how s3 is composed with s1 and s2
initial begin: string_builtin_functionstring 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 strings3 {s1.len()s2.len(){ }}; // try to comment this line and check the resultfor(int i0; is1.len()s2.len(); i) begins3[i] i s1.len() ? s1[i] : s2[i-s1.len()];end$display(s3 content: %s, s3);
endendmodule数组类型
合并非合并、赋值与循环、动态数组、队列、关联数组
module array_type;bit b_unpacked_vs_packed 1;
bit b_array_assigment_and_loop 1;
bit b_dynamic_array 1;
bit b_queue_use 1;
bit b_associate_array 1;// TODO-1 learn the difference between unpacked and packed data storage and
// assignment
initial begin: unpacked_vs_packedbit [7:0] unpacked_word [3:0];bit [3:0] [7:0] packed_word;wait(b_unpacked_vs_packed 1); $display(unpacked_vs_packed process block started);// legal assignmentunpacked_word[0] 10;unpacked_word[1] 32;unpacked_word[2] 54;unpacked_word[3] 76;$display(unpacked_word %p, unpacked_word);// legal assignment with {}unpacked_word {76, 54, 32, 10};$display(unpacked_word %p, unpacked_word);// legal assignmentpacked_word[0] 10;packed_word[1] 32;packed_word[2] 54;packed_word[3] 76;$display(packed_word %p, packed_word);// legal assignment with {} but without packed_word {76, 54, 32, 10};$display(packed_word %p, packed_word);// legal assignment directly like a vector packedt_word[31:0]packed_word (7624) (5416) (328) 10;$display(packed_word %p, packed_word);// illegal assignment// packed_word unpacked_word [X]// unpacked_word packed_word [X]// illegal assignment between packed and unpacked arrayforeach(packed_word[i])packed_word[i] unpacked_word[i];foreach(unpacked_word[i])unpacked_word[i] packed_word[i];
end// TODO-2 learn the array assignment and foreach loop indexing method
initial begin: array_assigment_and_loopinteger sum [4][2]; // 8*4 size arraywait(b_array_assigment_and_loop 1); $display(array_assigment_and_loop process block started);// concatenation and default valuesum {0:{h21, h43}, default:{default:x}};// foreach loop indexingforeach(sum[i, j]) begin$display(sum[%0d][%0d] h%0x, i, j, sum[i][j]);end
end// TODO-3 learn the dynamic array basics
initial begin: dynamic_arrayint dyn1[], dyn2[];wait(b_dynamic_array 1); $display(dynamic_array process block started);dyn1 {1, 2, 3, 4};$display(dyn1 %p, dyn1);// copp method option-1dyn2 dyn1;$display(dyn2 %p, dyn2);$display(dyn2 size is %0d, dyn2.size());// copp method option-2dyn2 new[dyn1.size()](dyn1);$display(dyn2 %p, dyn2);$display(dyn2 size is %0d, dyn2.size());dyn2.delete();$display(dyn2 size is %0d, dyn2.size());
end// TODO-4: learn queue use
initial begin: queue_useint que1[$], que2[$];wait(b_queue_use 1); $display(queue_use process block started);que1 {10, 30, 40};$display(que1 %p, que1);que2 que1;$display(que2 %p, que1);que1.insert(1, 20);$display(que1 %p, que1);que1.delete(3); // delete que1[3]40void(que1.pop_front()); // pop que[0]10$display(que1 %p, que1);que1.delete();$display(que1 %p, que1);
end// TODO-5 learn associate array use
initial begin: associate_arrayint id_score1[int], id_score2[int]; // key ID, value SCOREwait(b_associate_array 1); $display(associate_array process block started);id_score1[101] 111;id_score1[102] 222;id_score1[103] 333;id_score1[104] 444;id_score1[105] 555;// associate array copyid_score2 id_score1;id_score2[101] 101;id_score2[102] 102;id_score2[103] 103;id_score2[104] 104;id_score2[105] 105;foreach(id_score1[id]) begin$display(id_score1[%0d] %0d, id, id_score1[id]);endforeach(id_score2[id]) begin$display(id_score2[%0d] %0d, id, id_score2[id]);end
endendmodule接口的定义与例化
接口里也可以定义方法
// TODO-1 understand how the interface is defined and instantied
// TODO-2 check how to define methods inside interface and call them internally or externally
// TODO-3 understand how to prepare transactions, drive them and monitor them
module interface_type;typedef struct {bit[7:0] addr;bit[31:0] data;bit write;int id;} trans_t;// struct print utility functionfunction void trans_print(trans_t t, string name trans);string s;s $sformatf(%s struct content is as below \n, name);s $sformatf(%s\taddr h%2x \n, s, t.addr);s $sformatf(%s\tdata h%8x \n, s, t.data);s $sformatf(%s\twrite b%0b \n, s, t.write);s $sformatf(%s\tid h%8x \n, s, t.id);$display(%s, s);endfunctioninterface intf1;logic [7:0] addr;logic [31:0] data;logic write;int id;// transaction drive tasktask drive_trans(trans_t t);addr t.addr ;data t.data ;write t.write;id t.id ;endtask// transaction monitor tasktask mon_trans(output trans_t t);t.addr addr ;t.data data ;t.write write;t.id id ;endtaskendinterface// interface instantiationintf1 if1();initial begintrans_t trans_in[3], trans_mon[3];// stimulus preparationtrans_in {{h10, h1122_3344, b1, h1000},{h14, h5566_7788, b0, h1001},{h18, h99AA_BBCC, b1, h1002}};foreach(trans_in[i]) begin#10;// stimulus driveif1.drive_trans(trans_in[i]);trans_print(trans_in[i], $sformatf(trans_in[%0d],i));#10;// stimulus monitorif1.mon_trans(trans_mon[i]);trans_print(trans_mon[i], $sformatf(trans_mon[%0d],i));// transaction comparisonif(trans_in[i] trans_mon[i])$display(trans_in[%0d] trans_mon[%0d], i, i);else$error(trans_in[%0d] ! trans_mon[%0d], i, i);endendendmodule类的封装
module class_encapsulation;bit b_object_instantiation 1;class chnl_trans;bit[31:0] data[];int ch_id;int pkt_id;int data_nidles;int pkt_nidles;bit rsp;int obj_id;static int global_obj_id 0;function new();global_obj_id;obj_id global_obj_id;endfunctionfunction chnl_trans clone();chnl_trans c new();c.data this.data;c.ch_id this.ch_id;c.pkt_id this.pkt_id;c.data_nidles this.data_nidles;c.pkt_nidles this.pkt_nidles;c.rsp this.rsp;return c;endfunctionfunction string sprint();string s;s {s, $sformatf(obj_id %0d: \n, this.obj_id)};foreach(data[i]) s {s, $sformatf(data[%0d] %8x \n, i, this.data[i])};s {s, $sformatf(ch_id %0d: \n, this.ch_id)};s {s, $sformatf(pkt_id %0d: \n, this.pkt_id)};s {s, $sformatf(data_nidles %0d: \n, this.data_nidles)};s {s, $sformatf(pkt_nidles %0d: \n, this.pkt_nidles)};s {s, $sformatf(rsp %0d: \n, this.rsp)};return s;endfunctionendclass: chnl_trans// TODO-1 learn the object instantiation
// TODO-2 learn the handle pointting to an object
// TODO-3 learn the class function clone()/sprint()
// TODO-4 compare if t1, t2 and t3 are pointting to the same object?
// TODO-5 check if the t1 pointted object data is exactly the same with the t3
// pointted object?
// TODO-6 learn how to call STATIC member variable/function, and their
// difference with local member variable/function
initial begin: object_instantiationchnl_trans t1, t2, t3;wait(b_object_instantiation 1); $display(b_object_instantiation process block started);t1 new();t1.data {1, 2, 3, 4};t1.ch_id 2;t1.pkt_id 100;t2 t1;$display(t1 object content is as below:\n%s, t1.sprint());$display(t2 object content is as below:\n%s, t2.sprint());t3 t1.clone();$display(t3 object content is as below:\n%s, t3.sprint());$display(t1 object ID is [%0d], t1.obj_id);$display(t2 object ID is [%0d], t2.obj_id);$display(t3 object ID is [%0d], t3.obj_id);$display(the latest chnl_trans object iD is [%0d], chnl_trans::global_obj_id);
endendmodule类的继承
module class_inheritance;bit b_member_override 1;class trans;bit[31:0] data[];int pkt_id;int data_nidles;int pkt_nidles;bit rsp;function trans clone(trans t null);if(t null) t new();t.data data;t.pkt_id pkt_id;t.data_nidles data_nidles;t.pkt_nidles pkt_nidles;t.rsp rsp;return t;endfunctionendclassclass chnl_trans extends trans;int ch_id; // new member in child class// member function override with// same function name, arguments, and return type// TODO-1 seperately enable the clone function-1 and function-2, and check// if both of them works, and compare which is better, and why?// clone function-1function trans clone(trans t null);chnl_trans ct;if(t null)ct new();elsevoid($cast(ct, t));ct.data data;ct.pkt_id pkt_id;ct.data_nidles data_nidles;ct.pkt_nidles pkt_nidles;ct.rsp rsp;ct.ch_id ch_id; // new memberreturn ct;endfunction// clone function-2// function trans clone(trans t null);// chnl_trans ct;// if(t null)// ct new();// else// void($cast(ct, t));// void(super.clone(ct));// ct.ch_id ch_id; // new member// return ct;// endfunctionendclassinitial begin: member_overridetrans t1, t2;chnl_trans ct1, ct2;wait(b_member_override 1); $display(b_member_override process block started);ct1 new();ct1.pkt_id 200;ct1.ch_id 2;// t1 pointed to ct1s trans class data baset1 ct1;// t2 copied ct1s trans class data baset2 ct1.clone();void($cast(ct2, t2));// TODO-2 why could not clone t1(-ct1) to t2?// t2 t1.clone(); // ERROR clone call// void($cast(ct2, t2));$display(ct1.pkt_id %0d, ct1.ch_id %0d, ct1.pkt_id, ct1.ch_id);// TODO-3 uncomment the statement below and consider// why t1 could not point to ct1.ch_id?// $display(ct1.pkt_id %0d, ct1.ch_id %0d, t1.pkt_id, t1.ch_id);$display(ct2.pkt_id %0d, ct2.ch_id %0d, ct2.pkt_id, ct2.ch_id);endendmodulepackage的使用
package sky_pkg;class sun;typedef enum {RISE, FALL} state_e;state_e state RISE;endclasssun apollo new();class cloud;endclass
endpackagepackage sea_pkg;class fish;endclassclass island;string name;function new(string name island);this.name name;endfunctionendclassisland hainan new(hainan);
endpackagemodule package_usage;import sky_pkg::cloud;import sea_pkg::*;import sea_pkg::hainan;// TODO-2 why hainan could not be delcared here?// island hainan;initial begin// TODO-1 why sun type is not recognized? how to make it recognizable?// sun s;// TODO-2 why hainan could be declared here?island hainan;// TODO-3 why apollo is not recognized?// $display(sun state is %s, apollo.state);hainan new(HAINAN);$display(hainan name is %s, hainan.name);$display(sea_pkg::hainan name is %s, sea_pkg::hainan.name);end
endmodule随机约束
module constrained_random;bit b_system_random_func 1;
bit b_class_randomization 1;// TODO-1 understand how to use system random function, and its advanced
// method such as to generate unique values
initial begin: system_random_funcint unsigned rval;int unsigned gen_vals[$];wait(b_system_random_func 1); $display(b_system_random_func process block started);// randomize 10 times, and each rand value doesnot care previous generated// valuerepeat(10) beginrval $urandom_range(0, 9);$display($urandom_range(0, 9) generated rand value is %0d, rval);end// Do you have other ways to generate unique number each time which should// not be duplicated with previously generate ones?repeat(10) begin$display(gen_vals queue content is %p, gen_vals);std::randomize(rval) with {foreach(gen_vals[i]) rval ! gen_vals[i]; rval inside {[0:9]};};gen_vals.push_back(rval);$display(std::randomize with inline constrait generated rand value %0d, rval);end
endclass chnl_trans;rand bit[31:0] data[];rand int ch_id;rand int pkt_id;rand int data_nidles;rand int pkt_nidles;bit rsp;constraint cstr{data.size inside {[4:8]};foreach(data[i]) data[i] hC000_0000 (this.ch_id24) (this.pkt_id8) i;ch_id 1;pkt_id 1;data_nidles inside {[0:2]};pkt_nidles inside {[1:10]};};endclass// TODO-2 learn basic constraint format, class randomization method, soft
// constraint, and how to avolid constraint conflict?
initial begin: class_randomizationchnl_trans ct1, ct2;wait(b_class_randomization 1); $display(b_class_randomization process block started);ct1 new();// is ct1 already randomized?$display(ct1.data.size %0d, ct1.ch_id %0d, ct1.pkt_id %0d, ct1.data.size(), ct1.ch_id, ct1.pkt_id);ct2 new();// is ct2 already randomized?$display(ct2.data.size %0d, ct2.ch_id %0d, ct2.pkt_id %0d, ct2.data.size(), ct2.ch_id, ct2.pkt_id);// why ct2.ch_id and ct2.pkt_id kept the same number even though it has been// randomized several times?repeat(5) beginvoid(ct2.randomize());$display(ct2.data.size %0d, ct2.ch_id %0d, ct2.pkt_id %0d, ct2.data.size(), ct2.ch_id, ct2.pkt_id);end// the randomization with inline constraint would meets randomization// failure, how to modify?// if(!ct1.randomize() with {ch_id 2;})// $error(ct1 randomization failure!);// else// $display(ct1.data.size %0d, ct1.ch_id %0d, ct1.pkt_id %0d, ct1.data.size(), ct1.ch_id, ct1.pkt_id);
endendmodule线程的同步
module thread_sync;bit b_event_use 0;
bit b_mailbox_use 1;
bit b_mailbox_user_define 1;// TODO-1.1 event does not new()
// TODO-1.2 learn event copy (direct assignment between two events)
// TODO-1.3 compare operator and triggered() method
initial begin: event_useevent e1, e2, e3a, e3b;wait(b_event_use 1); $display(b_event_use process block started);e3b e3a; // event copy, e3b and e3a are the same event-e1; // trigger e1 before e1;-e2; // trigger e2 before e2.triggered();forkbegin e1; $display(%0t, e1 finished , $time); endbegin wait(e2.triggered()); $display(%0t, wait(e2.triggered()) finished , $time); endbegin e3a; $display(%0t, e3a finished, $time); endbegin e3b; $display(%0t, e3b finished, $time); endjoin_none#10ns;- e3a;#10ns;- e1; // trigger e1 again
endclass box;int id;function new(int id);this.id id;endfunction
endclass// TODO-2 learn the parameterized mailbox and general storage method
initial begin: mailbox_usemailbox #(int) mb_id;mailbox #(box) mb_handle;box bx[5];wait(b_mailbox_use 1); $display(b_mailbox_use process block started);// mailbox need new(N) for instantiationmb_id new();mb_handle new();// mailbox storageforeach(bx[i]) beginbx[i] new(i);mb_id.put(i);mb_handle.put(bx[i]);end$display(box handles array bx content is %p, bx);// mailbox extraction$display(extracting ID and HANDLE from the TWO mailboxes);repeat(mb_id.num()) beginint id;box handle;mb_id.get(id);mb_handle.get(handle);$display(ID:%0d, HANDLE:%p, id, handle);end// check mailbox size$display(ID mailbox size is %0d, mb_id.num());$display(HANDLE mailbox size is %0d, mb_handle.num());
end// TODO-3 learn how to maximal utilize the mailbox storage with user defined
// type, we modify the mailbox_use block and give a new block
// mailbox_user_define
typedef struct{int id;box handle;
} mb_pair_element_t;initial begin: mailbox_user_definemailbox #(mb_pair_element_t) mb_pair;box bx[5];wait(b_mailbox_user_define 1); $display(b_mailbox_user_define process block started);// mailbox need new(N) for instantiationmb_pair new();// mailbox storageforeach(bx[i]) beginbx[i] new(i);mb_pair.put({i, bx[i]});end$display(box handles array bx content is %p, bx);// mailbox extraction$display(extracting ID and HANDLE from the ONE mailbox);repeat(mb_pair.num()) beginmb_pair_element_t pair;mb_pair.get(pair);$display(ID:%0d, HANDLE:%p, pair.id, pair.handle);end// check mailbox size$display(PAIR mailbox size is %0d, mb_pair.num);
endendmodule线程的控制
module thread_control;bit b_fork_join 1;
bit b_fork_join_any 0;
bit b_fork_join_none 0;class box;int id;function new(int id);this.id id;endfunction
endclassbox bx[3];task automatic thread(int id 1, int t 10);$display(%0t, thread id:%0d entered, $time, id);bx[id] new(id); // allocate space#(t*1ns);bx[id] null; // deallocate space$display(%0t, thread id:%0d exited, $time, id);
endtask// TODO-1 learn fork-join thread exited when all sub-thread exit.
initial begin: fork_joinwait(b_fork_join 1); $display(b_fork_join process block started);bx {null, null, null};$display(%0t, fork_join_thread entered, $time);fork: fork_join_threadthread(0, 10);thread(1, 20);thread(2, 30);join$display(%0t, fork_join_thread exited, $time);$display(%0t, box handles array is %p, $time, bx);#10;b_fork_join 0;b_fork_join_any 1;
end// TODO-2.1 learn fork-join_any thread exited when just one sub-thread exites,
// but all other sub-thread are still running.
// TODO-2.2 learn disable BLOCK/fork statement, and check if the running
// sub-threads haven been disabled.
initial begin: fork_join_anywait(b_fork_join_any 1); $display(b_fork_join_any process block started);bx {null, null, null};$display(%0t, fork_join_any_thread entered, $time);fork: fork_join_any_threadthread(0, 10);thread(1, 20);thread(2, 30);join_any$display(%0t, fork_join_any_thread exited, $time);$display(%0t, box handles array is %p, $time, bx);disable fork_join_any_thread;$display(%0t, disabled fork_join_any_thread, $time);#100ns;$display(%0t, box handles array is %p, $time, bx);#10ns;b_fork_join_any 0;b_fork_join_none 1;
end// TODO-3.1 learn fork-join_none thread exited directly without calling any
// sub-thread, and continue executing other statements. Then the
// fork-join_none sub-threads would be still running.
// TODO-3.2 learn the wait fork statement, and check the time after it is
// satisified. The time should be the point when all fork sub-thread finished.
initial begin: fork_join_nonewait(b_fork_join_none 1); $display(b_fork_join_none process block started);bx {null, null, null};$display(%0t, fork_join_none_thread entered, $time);fork: fork_join_none_threadthread(0, 10);thread(1, 20);thread(2, 30);join_none$display(%0t, fork_join_none_thread exited, $time);$display(%0t, box handles array is %p, $time, bx);#15ns;$display(%0t, box handles array is %p, $time, bx);wait fork;$display(%0t, fork_join_none_threads all sub-threads finished, $time);$display(%0t, box handles array is %p, $time, bx);
endendmodule虚方法
// This example is referred to the lec2/class_inheritance
// The purpose is to learn the convenience of virtual method
module virtual_methods;class trans;bit[31:0] data[];int pkt_id;int data_nidles;int pkt_nidles;bit rsp;virtual function trans clone(trans t null);if(t null) t new();t.data data;t.pkt_id pkt_id;t.data_nidles data_nidles;t.pkt_nidles pkt_nidles;t.rsp rsp;return t;endfunctionendclassclass chnl_trans extends trans;int ch_id; // new member in child classvirtual function trans clone(trans t null);chnl_trans ct;if(t null)ct new();elsevoid($cast(ct, t));void(super.clone(ct));ct.ch_id ch_id; // new memberreturn ct;endfunctionendclassinitial begintrans t1, t2;chnl_trans ct1, ct2;ct1 new();ct1.pkt_id 200;ct1.ch_id 2;// t1 pointed to ct1s trans class data baset1 ct1;$display(before cloning ct1 object);$display(ct1.pkt_id %0d, ct1.ch_id %0d, ct1.pkt_id, ct1.ch_id);// TODO-1 compare with lec2/class_inheritance TODO-2// why it is legal to call t1.clone() here?// TODO-2 via this example, please summarize the virtual method// conveniencet2 t1.clone();void($cast(ct2, t2));// TODO-3 to access ct2.ch_id, could we directly use t2.ch_id?// is it possible to add modified virtual before chnl_trans::ch_id, and// then access it by t2.ch_id? and why?$display(after cloning ct1 object);$display(ct1.pkt_id %0d, ct1.ch_id %0d, ct1.pkt_id, ct1.ch_id);$display(ct2.pkt_id %0d, ct2.ch_id %0d, ct2.pkt_id, ct2.ch_id);endendmodule方法任务与函数
module task_and_function;bit b_function_define 1;
bit b_task_define 1;
bit b_inout_vs_ref 1;function int double_f0(int a);return 2*a;
endfunctionfunction void double_f1(input int a, output int b);b 2*a;
endfunctionfunction void double_f2(inout int a);a 2*a;
endfunctionfunction automatic void double_f3(ref int a);a 2*a;
endfunctiontask double_t1(input int a, output int b);b 2*a;
endtasktask double_t2(inout int a);a 2*a;
endtasktask automatic double_t3(ref int a);a 2*a;
endtasktask double_t2_delay(inout int a);a 2*a;#10ns;
endtasktask automatic double_t3_delay(ref int a);a 2*a;#10ns;
endtask// TODO-1 lear the function definition possible ways
initial begin: function_defineint v1, v2;wait(b_function_define 1); $display(b_function_define process block started);v1 10;v2 double_f0(v1);$display(v1 %0d, double function result is %0d, v1, v2);v1 10;double_f1(v1, v2);$display(v1 %0d, double function result is %0d, v1, v2);v1 10;$display(v1 is %0d before calling double_f2(v1), v1);double_f2(v1);$display(v1 is %0d (result) after calling double_f2(v1), v1);v1 10;$display(v1 is %0d before calling double_f3(v1), v1);double_f3(v1);$display(v1 is %0d (result) after calling double_f3(v1), v1);
end// TODO-2 learn the task definition possible ways
initial begin: task_defineint v1, v2;wait(b_task_define 1); $display(b_task_define process block started);v1 10;double_t1(v1, v2);$display(v1 %0d, double task result is %0d, v1, v2);v1 10;$display(v1 is %0d before calling double_t2(v1), v1);double_t2(v1);$display(v1 is %0d (result) after calling double_t2(v1), v1);v1 10;$display(v1 is %0d before calling double_t3(v1), v1);double_t3(v1);$display(v1 is %0d (result) after calling double_t3(v1), v1);
end// TODO-3 compare the inout and ref argument between function and task use
initial begin: inout_vs_refint v1, v2;wait(b_inout_vs_ref 1); $display(b_inout_vs_ref process block started);v1 10;$display(v1 is %0d before calling double_t2_delay(v1), v1);forkdouble_t2_delay(v1);begin #5ns; $display(%0t v1 %0d in task call double_t2_delay(v1), $time, v1); endjoin$display(v1 is %0d (result) after calling double_t2_delay(v1), v1);v1 10;$display(v1 is %0d before calling double_t3_delay(v1), v1);forkdouble_t3_delay(v1);begin #5ns; $display(%0t v1 %0d in task call double_t3_delay(v1), $time, v1); endjoin$display(v1 is %0d (result) after calling double_t3_delay(v1), v1);
endendmoduleSV用于设计
module sv_for_design;bit b_always_compare 1;
bit b_compare_operator 1;
bit b_inside_operator 1;
bit b_case_statement 1;// TODO-1 why l2 ! l3 at time 0 ?
logic l1 0, l2, l3;
always (l1) l2 l1;
always_comb l3 l1;
initial begin: always_comparewait(b_always_compare 1); $display(always_compare process block started);#0;$display(%0t, l2 %b, $time, l2);$display(%0t, l3 %b, $time, l3);#10;l1 1;#1;$display(%0t, l2 %b, $time, l2);$display(%0t, l3 %b, $time, l3);
end// TODO-2 learn the compare operators difference
initial begin: compare_operatorlogic [3:0] v1, v2;wait(b_compare_operator 1); $display(compare_operator process block started);v1 b111x;v2 b1110;if(v1 ! v2) // binary logical equality operator$display(v1 %b ! v2 %b, v1, v2);else$display(v1 %b v2 %b, v1, v2);$display(the operator result (v1 ! v2) is %b, (v1 ! v2));if(v1 ! v2) // binary case equality operator$display(v1 %b ! v2 %b, v1, v2);else$display(v1 %b v2 %b, v1, v2);$display(the operator result (v1 ! v2) is %b, (v1 ! v2));end// TODO-3 learn the inside operator
initial begin: inside_operatorbit [2:0] v1;wait(b_inside_operator 1); $display(inside_operator process block started);v1 b100;if(v1 b100 || v1 b010 || v1 b001)$display(v1: %0b meets onehot vector requirement!, v1);else$display(v1: %0b does not meet onehot vector requirement!, v1);if(v1 inside {b100, b010, b001})$display(v1: %0b meets onehot vector requirement!, v1);else$display(v1: %0b does not meet onehot vector requirement!, v1);if($onehot(v1) 1)$display(v1: %0b meets onehot vector requirement!, v1);else$display(v1: %0b does not meet onehot vector requirement!, v1);
end// TODO-4 learn {unique, priority} case{ ,x, z} statement
initial begin: case_statementparameter width_p 4;bit [width_p-1:0] v_arr[3];wait(b_case_statement 1); $display(case_statement process block started);v_arr {b1000, b1111, b0110};foreach(v_arr[i]) beginunique case(v_arr[i])b0001, b0010, b0100, b1000: $display(v1: %0b meets onehot vector requirement!, v_arr[i]);0: $display(v1: %0b is ZERO, v_arr[i]);b1111: $display(v1: %0b is ALL ONES, v_arr[i]);default: $display(v1: %0b has [2~%0d] ones, v_arr[i], width_p-1);endcaseend
endendmodule
参考资料
Wenhui’s Rotten PenSystemVerilogchipverify