日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

uvm 形式验证_UVM基础

發布時間:2024/9/27 编程问答 54 豆豆
生活随笔 收集整理的這篇文章主要介紹了 uvm 形式验证_UVM基础 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

uvm_component與uvm_object

1.

幾乎所有的類都派生于uvm_object,包括uvm_component。

uvm_component有兩大特性是uvm_object所沒有的:

  • 一是通過在new的時候指定parent參數來形成一種樹形的組織結構;
  • 二是有phase的自動執行特點。

下圖是常用的UVM繼承關系:

從圖中可以看出,從uvm_object派生出了兩個分支,所有的UVM樹的結點都是由uvm_component組成的,只有基于uvm_component派生的類才可能成為UVM樹的結點;最左邊分支的類或者直接派生自uvm_object的類,是不可能以結點的形式出現在UVM樹上的。

2.

常用的派生自uvm_object類的有:

  • uvm_sequence_item:讀者定義的所有的transaction要從uvm_sequence_item派生。
  • uvm_sequence:所有的sequence要從uvm_sequence派生。
  • config:所有的config一般直接從uvm_object派生。config的主要功能就是規范驗證平臺的行為方式。之前我們已經見識了使用config_db進行參數配置,這里的config其實指的是把所有的參數放在一個object中。
  • uvm_reg_item:它派生自uvm_sequence_item,用于register model中。
  • uvm_reg_map、uvm_mem、uvm_reg_field、uvm_reg、uvm_reg_file、uvm_reg_block等與寄存器相關的眾多的類都是派生自uvm_object,它們都是用于register model。
  • uvm_phase:它派生自uvm_object,其主要作用為控制uvm_component的行為方式,使uvm_component平滑地在各個不同的phase之間依次運轉。

常用的派生自uvm_component類的有:

  • uvm_driver:所有的driver都要派生自uvm_driver。driver的功能主要就是向sequencer索要sequence_item(transaction),并且將sequence_item里的信息驅動到DUT的端口上,這相當于完成了從transaction級別到DUT能夠接受的端口級別信息的轉換。
  • uvm_monitor:所有的monitor都要派生自uvm_monitor。monitor做的事情與driver相反,driver向DUT的pin上發送數據,而monitor則是從DUT的pin上接收數據,并且把接收到的數據轉換成transaction級別的sequence_item,再把轉換后的數據發送給scoreboard,供其做比較。
  • uvm_scoreboard:一般的scoreboard都要派生自uvm_scoreboard。scoreboard的功能就是比較reference model和monitor分別發送來的數據,根據比較結果判斷DUT是否正確工作。
  • reference model:UVM中并沒有針對reference model定義一個類。所以通常來說,reference model都是直接派生自uvm_component。reference model的作用就是模仿DUT,完成與DUT相同的功能。
  • uvm_agent:所有的agent要派生自uvm_agent。與前面幾個比起來,uvm_agent的作用并不是那么明顯。它只是把driver和monitor封裝在一起,根據參數值來決定是只實例化monitor還是要同時實例化driver和monitor。
  • uvm_env:所有的env(environment的縮寫)要派生自uvm_env。env將驗證平臺上用到的固定不變的component都封裝在一起。這樣,當要運行不同的測試用例時,只要在測試用例中實例化此env即可。

3.

在UVM中與uvm_object相關的factory宏有如下幾個:

  • uvm_object_utils:它用于把一個直接或間接派生自uvm_object的類注冊到factory中。
  • uvm_object_param_utils:它用于把一個直接或間接派生自uvm_object的參數化的類注冊到factory中。
  • uvm_object_utils_begin:這個宏在第2章介紹my_transaction時出現過,當需要使用field_automation機制時,需要使用此宏。
  • uvm_object_param_utils_begin:與uvm_object_utils_begin宏一樣,只是它適用于參數化的且其中某些成員變量要使用field_automation機制實現的類。
  • uvm_object_utils_end:它總是與uvm_object_*_begin成對出現,作為factory注冊的結束標志。

在UVM中與uvm_component相關的factory宏有如下幾個:

  • uvm_component_utils:它用于把一個直接或間接派生自uvm_component的類注冊到factory中。
  • uvm_component_param_utils:它用于把一個直接或間接派生自uvm_component的參數化的類注冊到factory中。
  • uvm_component_utils_begin:這個宏與uvm_object_utils_begin相似,它用于同時需要使用factory機制和field_automation機制注冊的類。注意主要為了可以自動地使用config_db來得到某些變量的值,而不是在component中使用field_automation機制。
  • uvm_component_param_utils_begin:與uvm_component_utils_begin宏一樣,只是它適用于參數化的,且其中某些成員變量要使用field_automation機制實現的類。
  • uvm_component_utils_end:它總是與uvm_component_*_begin成對出現,作為factory注冊的結束標志。

4.

雖說uvm_component是從uvm_object派生來的,但作為UVM的結點,這使得其失去了某些uvm_object的特性。

比如在uvm_object中有clone函數,它用于分配一塊內存空間,并把另一個實例復制到這塊新的內存空間中。clone函數的使用方式如下:

class A extends uvm_object;… endclassclass my_env extends uvm_env;virtual function void build_phase(uvm_phase phase);A a1;A a2;a1 = new("a1");a1.data = 8'h9;$cast(a2, a1.clone());endfunction endclass

上述的clone函數無法用于uvm_component中,因為一旦使用后,新clone出來的類,其parent參數無法指定。

雖然uvm_component無法使用clone函數,但是可以使用copy函數。因為在調用copy之前,目標實例已經完成了實例化,其parent參數已經指定了。

UVM的樹形結構

1.

一般在使用時,parent通常都是this。假設A和B均派生自uvm_component,在A中實例化一個B:

class B extends uvm_component;… endclass class A extends uvm_component;B b_inst;virtual function void build_phase(uvm_phase phase);b_inst = new("b_inst", this);endfunction endclass

在b_inst實例化的時候,把this指針傳遞給了它,代表A是b_inst的parent。一種常見的觀點是,b_inst是A的成員變量,自然而然的,A就是b_inst的parent了。

當b_inst實例化的時候,指定一個parent的變量,同時在每一個component的內部維護一個數組 m_children,當b_inst實例化時,就把b_inst的指針加入到A的m_children數組中。只有這樣才能讓A知道b_inst是自己的孩子,同時也才能讓b_inst知道A是自己的父母。當b_inst有了自己的孩子時,即在b_inst的m_children中加入孩子的指針。

2.

樹根應該就是uvm_test。在測試用例里實例化env,在env里實例化scoreboard、reference model、agent、在agent里面實例化sequencer、driver和monitor。

UVM中真正的樹根是一個稱為uvm_top的東西,完整的UVM樹如下圖所示。

uvm_top是一個全局變量,它是uvm_root的一個實例。而uvm_root派生自uvm_component,所以uvm_top本質上是一個uvm_component。uvm_test_top的parent是uvm_top,而uvm_top的parent則是null。

如果一個component在實例化時,其parent被設置為null,那么這個component的parent將會被系統設置為系統中唯一的uvm_root的實例uvm_top。如下圖所示:

可見,uvm_root的存在可以保證整個驗證平臺中只有一棵樹,所有結點都是uvm_top的子結點。

而在之前我們的驗證平臺中這個parent被設置為null的節點為my_casen,因此其被設置為系統中唯一的uvm_root的實例uvm_top,而我們可以在仿真編譯時通過UVM_TESTNAME來指定選擇哪個case來進行仿真測試。

另外這里my_casen派生自base_test,但并不因此增加UVM的層級,因此其parent為null。

在驗證平臺中,有時候需要得到uvm_top,由于uvm_top是一個全局變量,可以直接使用uvm_top。除此之外,還可以使用如下的方式得到它的指針:

uvm_root top; top=uvm_root::get();

3.

UVM提供了一系列的接口函數用于訪問UVM樹中的結點。這其中最主要的是以下幾個:

  • get_parent函數,用于得到當前實例的parent。
extern virtual function uvm_component get_parent ();
  • 與get_parent相對的就是get_child函數。與get_parent不同的是,get_child需要一個string類型的參數name,表示此child實例在實例化時指定的名字。因為一個component只有一個parent,所以get_parent不需要指定參數;而可能有多個child,所以必須指定name參數。
extern function uvm_component get_child (string name);
  • 為了得到所有的child,可以使用get_children函數:
extern function void get_children(ref uvm_component children[$]);

使用方法為:

uvm_component array[$]; my_comp.get_children(array); foreach(array[i])do_something(array[i]);//自定義函數
  • 除了一次性得到所有的child外,還可以使用get_first_child和get_next_child的組合依次得到所有的child:
string name; uvm_component child; if (comp.get_first_child(name)) do beginchild = comp.get_child(name);child.print(); end while (comp.get_next_child(name));

這兩個函數的使用依賴于一個string類型的name。在這兩個函數的原型中,name是作為ref類型傳遞的

extern function int get_first_child (ref string name); extern function int get_next_child (ref string name);
  • get_num_children函數用于返回當前component所擁有的child的數量:
extern function int get_num_children ();

field automation機制

1.

最簡單的uvm_field系列宏有如下幾種:

`define uvm_field_int(ARG,FLAG) `define uvm_field_real(ARG,FLAG) `define uvm_field_enum(T,ARG,FLAG) `define uvm_field_object(ARG,FLAG) `define uvm_field_event(ARG,FLAG) `define uvm_field_string(ARG,FLAG)

上述幾個宏分別用于要注冊的字段是整數、實數、枚舉類型、直接或間接派生自uvm_object的類型、事件及字符串類型。

與動態數組有關的uvm_field系列宏有:

`define uvm_field_array_enum(ARG,FLAG) `define uvm_field_array_int(ARG,FLAG) `define uvm_field_array_object(ARG,FLAG) `define uvm_field_array_string(ARG,FLAG)

與靜態數組相關的uvm_field系列宏有:

`define uvm_field_sarray_int(ARG,FLAG) `define uvm_field_sarray_enum(ARG,FLAG) `define uvm_field_sarray_object(ARG,FLAG) `define uvm_field_sarray_string(ARG,FLAG)

與隊列相關的uvm_field系列宏有:

`define uvm_field_queue_enum(ARG,FLAG) `define uvm_field_queue_int(ARG,FLAG) `define uvm_field_queue_object(ARG,FLAG) `define uvm_field_queue_string(ARG,FLAG)

與聯合數組相關的uvm_field宏有:

`define uvm_field_aa_int_string(ARG, FLAG) `define uvm_field_aa_string_string(ARG, FLAG) `define uvm_field_aa_object_string(ARG, FLAG) `define uvm_field_aa_int_int(ARG, FLAG) `define uvm_field_aa_int_int_unsigned(ARG, FLAG) `define uvm_field_aa_int_integer(ARG, FLAG) `define uvm_field_aa_int_integer_unsigned(ARG, FLAG) `define uvm_field_aa_int_byte(ARG, FLAG) `define uvm_field_aa_int_byte_unsigned(ARG, FLAG) `define uvm_field_aa_int_shortint(ARG, FLAG) `define uvm_field_aa_int_shortint_unsigned(ARG, FLAG) `define uvm_field_aa_int_longint(ARG, FLAG) `define uvm_field_aa_int_longint_unsigned(ARG, FLAG) `define uvm_field_aa_string_int(ARG, FLAG) `define uvm_field_aa_object_int(ARG, FLAG)

聯合數組有兩大識別標志,一是索引的類型,二是存儲數據的類型。在這一系列uvm_field宏中,出現的第一個類型是存儲數據類型,第二個類型是索引類型,如uvm_field_aa_int_string用于聲明那些存儲的數據是int,而其索引是string類型的聯合數組。

2.

field automation機制的常用函數有:

  • copy函數用于實例的復制,其原型為:
extern function void copy (uvm_object rhs);

如果要把某個A實例復制到B實例中,那么應該使用B.copy(A)。在使用此函數前,B實例必須已經使用new函數分配好了內存空間。

  • compare函數用于比較兩個實例是否一樣,其原型為:
extern function bit compare (uvm_object rhs, uvm_comparer comparer=null);

如果要比較A與B是否一樣,可以使用A.compare(B),也可以使用B.compare(A)。當兩者一致時,返回1;否則為0。

  • pack_bytes函數用于將所有的字段打包成byte流,其原型為:
extern function int pack_bytes (ref byte unsigned bytestream[],input uvm_packer packer=null);
  • unpack_bytes函數用于將一個byte流逐一恢復到某個類的實例中,其原型為:
extern function int unpack_bytes (ref byte unsigned bytestream[], input uvm_packer packer=null);
  • pack函數用于將所有的字段打包成bit流,其原型為:
extern function int pack (ref bit bitstream[],input uvm_packer packer=null);
  • pack函數的使用與pack_bytes類似。unpack函數用于將一個bit流逐一恢復到某個類的實例中,unpack的使用與unpack_bytes類似。
extern function int unpack (ref bit bitstream[],input uvm_packer packer=null);
  • pack_ints函數用于將所有的字段打包成int(4個byte,或者dword)流。
  • unpack_ints函數用于將一個int流逐一恢復到某個類的實例中
  • print函數用于打印所有的字段。
  • clone函數
  • 除了上述函數之外,field automation機制還提供自動得到使用config_db::set設置的參數的功能,之前講過,這里不再贅述。

3.

在post_randomize中計算CRC前先檢查一下crc_err字段,如果為1,那么直接使用隨機值,否則使用真實的CRC。

class my_transaction extends uvm_sequence_item;rand bit[47:0] dmac;rand bit[47:0] smac;rand bit[15:0] ether_type;rand byte pload[];rand bit[31:0] crc;rand bit crc_err;function void post_randomize();if(crc_err);//do nothingelsecrc = calc_crc;endfunction endclass

在sequence中可以使用如下方式產生CRC錯誤的激勵:

`uvm_do_with(tr, {tr.crc_err == 1;})

這里在后面的控制域中加入UVM_NOPACK的形式來實現對crc的控制。

`uvm_object_utils_begin(my_transaction) `uvm_field_int(dmac, UVM_ALL_ON) `uvm_field_int(smac, UVM_ALL_ON) `uvm_field_int(ether_type, UVM_ALL_ON) `uvm_field_array_int(pload, UVM_ALL_ON) `uvm_field_int(crc, UVM_ALL_ON) `uvm_field_int(crc_err, UVM_ALL_ON | UVM_NOPACK) `uvm_object_utils_end

UVM的這些標志位本身其實是一個17bit的數字:

parameter UVM_ALL_ON = 'b000000101010101; parameter UVM_COPY = (1<<0); parameter UVM_NOCOPY = (1<<1); parameter UVM_COMPARE = (1<<2); parameter UVM_NOCOMPARE = (1<<3); parameter UVM_PRINT = (1<<4); parameter UVM_NOPRINT = (1<<5); parameter UVM_RECORD = (1<<6); parameter UVM_NORECORD = (1<<7); parameter UVM_PACK = (1<<8); parameter UVM_NOPACK = (1<<9);

在這個17bit的數字中,bit0表示copy,bit1表示no_copy,bit2表示compare,bit3表示no_compare,bit4表示print,bit5表示no_print,bit6表示record,bit7表示no_record,bit8表示pack,bit9表示no_pack。剩余的7bit則另有它用,這里不做討論。UVM_ALL_ON的值是’b000000101010101,表示打開copy、compare、print、record、pack功能。UVM_ALL_ON|UVM_NOPACK的結果就是‘b000001101010101。這樣UVM 在執行pack操作時,首先檢查bit9,發現其為1,直接忽略bit8所代表的UVM_PACK。

4.

class my_transaction extends uvm_sequence_item;rand bit[47:0] smac;rand bit[47:0] dmac;rand bit[31:0] vlan[];rand bit[15:0] eth_type;rand byte pload[];rand bit[31:0] crc;`uvm_object_utils_begin(my_transaction)`uvm_field_int(smac, UVM_ALL_ON)`uvm_field_int(dmac, UVM_ALL_ON)`uvm_field_array_int(vlan, UVM_ALL_ON)`uvm_field_int(eth_type, UVM_ALL_ON)`uvm_field_array_int(pload, UVM_ALL_ON)`uvm_object_utils_end endclass

在隨機化普通以太網幀時,可以使用如下的方式:

my_transaction tr; tr = new(); assert(tr.randomize() with {vlan.size() == 0;});

協議中規定vlan的字段固定為4個字節,所以在隨機化VLAN幀時,可以使用如下的方式:

my_transaction tr; tr = new(); assert(tr.randomize() with {vlan.size() == 1;});

協議中規定vlan的4個字節各自有其不同的含義,這4個字節分別代表4個不同的字段。如果使用上面的方式,問題雖然解決了,但是這4個字段的含義不太明確。 一個可行的解決方案是:

class my_transaction extends uvm_sequence_item;rand bit[47:0] dmac;rand bit[47:0] smac;rand bit[15:0] vlan_info1;rand bit[2:0] vlan_info2;rand bit vlan_info3;rand bit[11:0] vlan_info4;rand bit[15:0] ether_type;rand byte pload[];rand bit[31:0] crc;rand bit is_vlan;`uvm_object_utils_begin(my_transaction)`uvm_field_int(dmac, UVM_ALL_ON)`uvm_field_int(smac, UVM_ALL_ON)if(is_vlan)begin`uvm_field_int(vlan_info1, UVM_ALL_ON)`uvm_field_int(vlan_info2, UVM_ALL_ON)`uvm_field_int(vlan_info3, UVM_ALL_ON)`uvm_field_int(vlan_info4, UVM_ALL_ON)end`uvm_field_int(ether_type, UVM_ALL_ON)`uvm_field_array_int(pload, UVM_ALL_ON)`uvm_field_int(crc, UVM_ALL_ON | UVM_NOPACK)`uvm_field_int(is_vlan, UVM_ALL_ON | UVM_NOPACK)`uvm_object_utils_end endclass

在隨機化普通以太網幀時,可以使用如下的方式:

my_transaction tr; tr = new(); assert(tr.randomize() with {is_vlan == 0;});

在隨機化VLAN幀時,可以使用如下的方式:

my_transaction tr; tr = new(); assert(tr.randomize() with {is_vlan == 1;});

使用這種方式的VLAN幀,在執行print操作時,4個字段的信息將會非常明顯;在調用compare函數時,如果兩個transaction不同,將會更加明確地指明是哪個字段不一樣。

UVM中打印信息的控制

1.

UVM通過冗余度級別的設置提高了仿真日志的可讀性。在打印信息之前,UVM會比較要顯示信息的冗余度級別與默認的冗余度閾值,如果小于等于閾值,就會顯示,否則不會顯示。默認的冗余度閾值是UVM_MEDIUM,所有低于等于UVM_MEDIUM(如UVM_LOW)的信息都會被打印出來。

可以通過get_report_verbosity_level函數得到某個component的冗余度閾值:

virtual function void connect_phase(uvm_phase phase);$display("env.i_agt.drv's verbosity level is %0d", env.i_agt.drv.get_report_verbosity_level()); endfunction

這個函數得到的是一個整數,它代表的含義如下所示:

typedef enum {UVM_NONE = 0,UVM_LOW = 100,UVM_MEDIUM = 200,UVM_HIGH = 300,UVM_FULL = 400,UVM_DEBUG = 500 } uvm_verbosity;

UVM提供set_report_verbosity_level函數來設置某個特定component的默認冗余度閾值。在base_test中將driver的冗余度閾值設置為UVM_HIGH(UVM_LOW、UVM_MEDIUM、UVM_HIGH的信息都會被打印)代碼為:

virtual function void connect_phase(uvm_phase phase);env.i_agt.drv.set_report_verbosity_level(UVM_HIGH); endfunction

把env.i_agt及其下所有的component的冗余度閾值設置為UVM_HIGH的代碼為:

env.i_agt.set_report_verbosity_level_hier(UVM_HIGH);

set_report_verbosity_level會對某個component內所有的uvm_info宏顯示的信息產生影響。如果這些宏在調用時使用了不同的ID:

`uvm_info("ID1", "ID1 INFO", UVM_HIGH) `uvm_info("ID2", "ID2 INFO", UVM_HIGH)

那么可以使用set_report_id_verbosity函數來區分不同的ID的冗余度閾值:

env.i_agt.drv.set_report_id_verbosity("ID1", UVM_HIGH);

除了在代碼中設置外,UVM支持在命令行中設置冗余度閾值:

<sim command> +UVM_VERBOSITY=UVM_HIGH 或者: <sim command> +UVM_VERBOSITY=HIGH

上述的命令行參數會把整個驗證平臺的冗余度閾值設置為UVM_HIGH。它幾乎相當于是在base_test中調用 set_report_verbosity_level_hier函數,把base_test及以下所有component的冗余度級別設置為UVM_HIGH:

set_report_verbosity_level_hier(UVM_HIGH)

綜上,通過設置不同env的冗余度級別,可以更好地控制整個芯片驗證環境輸出信息的質量。

2.

UVM默認有四種信息嚴重性:UVM_INFO、UVM_WARNING、UVM_ERROR、UVM_FATAL。這四種嚴重性可以互相重載。如果要把driver中所有的UVM_WARNING顯示為UVM_ERROR,可以使用如下的函數:

virtual function void connect_phase(uvm_phase phase);env.i_agt.drv.set_report_severity_override(UVM_WARNING, UVM_ERROR);//env.i_agt.drv.set_report_severity_id_override(UVM_WARNING, "my_driver", UVM_ERROR); endfunction

重載嚴重性可以只針對某個component內的某個特定的ID起作用:

env.i_agt.drv.set_report_severity_id_override(UVM_WARNING, "my_driver", UVM_ERROR);

3.

當uvm_fatal出現時,表示出現了致命錯誤,仿真會馬上停止。UVM同樣支持UVM_ERROR達到一定數量時結束仿真。實現這個功能的是set_report_max_quit_count函數,其調用方式為:

function void base_test::build_phase(uvm_phase phase);super.build_phase(phase);env = my_env::type_id::create("env", this);set_report_max_quit_count(5); endfunction

與set_max_quit_count相對應的是get_max_quit_count,可以用于查詢當前的退出閾值。

除了在代碼中使用set_max_quit_count設置外,還可以在命令行中設置退出閾值:

<sim command> +UVM_MAX_QUIT_COUNT=6,NO

在上一節中,當UVM_ERROR達到一定數量時,可以自動退出仿真。在計數當中,是不包含UVM_WARNING的。可以通過設置set_report_severity_action函數來把UVM_WARNING加入計數目標:

virtual function void connect_phase(uvm_phase phase);set_report_max_quit_count(5);env.i_agt.drv.set_report_severity_action(UVM_WARNING, UVM_DISPLAY|UVM_COUNT); endfunction

類似的遞歸調用方式:

env.i_agt.set_report_severity_action_hier(UVM_WARNING, UVM_DISPLAY| UVM_COUNT);

上述代碼把env.i_agt及其下所有結點的UVM_WARNING加入到計數目標中。

除了針對嚴重性進行計數外,還可以對某個特定的ID進行計數:

env.i_agt.drv.set_report_id_action("my_drv", UVM_DISPLAY| UVM_COUNT);

4.

在程序調試時,斷點功能是非常有用的一個功能。在程序運行時,預先在某語句處設置一斷點。當程序執行到此處時,停止仿真,進入交互模式,從而進行調試。

當env.i_agt.drv中出現UVM_WARNING時,立即停止仿真,進入交互模式。

virtual function void connect_phase(uvm_phase phase);env.i_agt.drv.set_report_severity_action(UVM_WARNING, UVM_DISPLAY| UVM_STOP); endfunction

5.

UVM提供將特定信息輸出到特定日志文件的功能:

將env.i_agt.drv的UVM_INFO輸出到info.log,UVM_WARNING輸出到warning.log,UVM_ERROR輸出到error.log,UVM_FATAL輸出到fatal.log。這里用到了set_report_severity_file函數。

UVM_FILE info_log; UVM_FILE warning_log; UVM_FILE error_log; UVM_FILE fatal_log; virtual function void connect_phase(uvm_phase phase);info_log = $fopen("info.log", "w");warning_log = $fopen("warning.log", "w");error_log = $fopen("error.log", "w");fatal_log = $fopen("fatal.log", "w");env.i_agt.drv.set_report_severity_file(UVM_INFO, info_log);env.i_agt.drv.set_report_severity_file(UVM_WARNING, warning_log);env.i_agt.drv.set_report_severity_file(UVM_ERROR, error_log);env.i_agt.drv.set_report_severity_file(UVM_FATAL, fatal_log);env.i_agt.drv.set_report_severity_action(UVM_INFO, UVM_DISPLAY| UVM_LOG);env.i_agt.drv.set_report_severity_action(UVM_WARNING, UVM_DISPLAY|UVM_LOG);env.i_agt.drv.set_report_severity_action(UVM_ERROR, UVM_DISPLAY| UVM_COUNT | UVM_LOG);env.i_agt.drv.set_report_severity_action(UVM_FATAL, UVM_DISPLAY|UVM_EXIT | UVM_LOG); endfunction

這個函數同樣有遞歸調用方式:

env.i_agt.set_report_severity_file_hier(UVM_INFO, info_log); env.i_agt.set_report_severity_file_hier(UVM_WARNING, warning_log); env.i_agt.set_report_severity_file_hier(UVM_ERROR, error_log); env.i_agt.set_report_severity_file_hier(UVM_FATAL, fatal_log); env.i_agt.set_report_severity_action_hier(UVM_INFO, UVM_DISPLAY| UVM_LOG); env.i_agt.set_report_severity_action_hier(UVM_WARNING, UVM_DISPLAY| UVM_LOG); env.i_agt.set_report_severity_action_hier(UVM_ERROR, UVM_DISPLAY| UVM_COUNT |UVM_LOG); env.i_agt.set_report_severity_action_hier(UVM_FATAL, UVM_DISPLAY| UVM_EXIT | UVM_LOG);

當然除了根據嚴重性設置不同的日志文件外,UVM中還可以根據不同的ID來設置不同的日志文件:

UVM_FILE driver_log; UVM_FILE drv_log; virtual function void connect_phase(uvm_phase phase);driver_log = $fopen("driver.log", "w");drv_log = $fopen("drv.log", "w");env.i_agt.drv.set_report_id_file("my_driver", driver_log);env.i_agt.drv.set_report_id_file("my_drv", drv_log);env.i_agt.drv.set_report_id_action("my_driver", UVM_DISPLAY| UVM_LOG);env.i_agt.drv.set_report_id_action("my_drv", UVM_DISPLAY| UVM_LOG); endfunction virtual function void final_phase(uvm_phase phase);$fclose(driver_log);$fclose(drv_log); endfunction

當然也有遞歸調用方式:

env.i_agt.set_report_id_file_hier("my_driver", driver_log); env.i_agt.set_report_id_file_hier("my_drv", drv_log); env.i_agt.set_report_id_action_hier("my_driver", UVM_DISPLAY| UVM_LOG); env.i_agt.set_report_id_action_hier("my_drv", UVM_DISPLAY| UVM_LOG);

UVM還可以根據嚴重性和ID的組合來設置不同的日志文件:

UVM_FILE driver_log; UVM_FILE drv_log; virtual function void connect_phase(uvm_phase phase);driver_log = $fopen("driver.log", "w");drv_log = $fopen("drv.log", "w");env.i_agt.drv.set_report_severity_id_file(UVM_WARNING, "my_driver",driver_log);env.i_agt.drv.set_report_severity_id_file(UVM_INFO, "my_drv", drv_log);env.i_agt.drv.set_report_id_action("my_driver", UVM_DISPLAY| UVM_LOG);env.i_agt.drv.set_report_id_action("my_drv", UVM_DISPLAY| UVM_LOG); endfunction

6.

UVM共定義了如下幾種行為:

typedef enum {UVM_NO_ACTION = 'b000000,UVM_DISPLAY = 'b000001,UVM_LOG = 'b000010,UVM_COUNT = 'b000100,UVM_EXIT = 'b001000,UVM_CALL_HOOK = 'b010000,UVM_STOP = 'b100000 } uvm_action_type;

與field automation機制中定義UVM_ALL_ON類似,這里也把UVM_DISPLAY等定義為一個整數。不同的行為有不同的位偏移,所以不同的行為可以使用“或”的方式組合在一起:

UVM_DISPLAY| UVM_COUNT | UVM_LOG

其中

  • UVM_NO_ACTION是不做任何操作;
  • UVM_DISPLAY是輸出到標準輸出上;
  • UVM_LOG是輸出到日志文件中,它能工作的前提是設置好了日志文件;
  • UVM_COUNT是作為計數目標;
  • UVM_EXIT是直接退出仿真;
  • UVM_CALL_HOOK是調用一個回調函數;
  • UVM_STOP是停止仿真,進入命令行交互模式。

默認情況下,UVM作如下的設置:

set_severity_action(UVM_INFO, UVM_DISPLAY); set_severity_action(UVM_WARNING, UVM_DISPLAY); set_severity_action(UVM_ERROR, UVM_DISPLAY | UVM_COUNT); set_severity_action(UVM_FATAL, UVM_DISPLAY | UVM_EXIT);

從UVM_INFO到UVM_FATAL,都會輸出到標準輸出中;UVM_ERROR會作為仿真退出計數器的計數目標;出現 UVM_FATAL時會自動退出仿真。之前是通過設置信息的冗余級別來打開或關閉信息的現實,其實也可以通過設置為UVM_NO_ACTION來實現。

virtual function void connect_phase(uvm_phase phase);env.i_agt.drv.set_report_severity_action(UVM_INFO, UVM_NO_ACTION); endfunction

無論原本的冗余度是什么,經過上述設置后,env.i_agt.drv的所有的uvm_info信息都不會輸出。

config_db機制

1.

一個component(如my_driver)內通過get_full_name()函數可以得到此component的路徑:

function void my_driver::build_phase();super.build_phase(phase);$display("%s", get_full_name()); endfunction

上述代碼如果是在層次結構中的my_driver中,那么打印出來的值是uvm_test_top.env.i_agt.drv。

為了方便,上圖使用了new函數而不是factory式的create方式來創建實例。在這幅圖中,uvm_test_top實例化時的名字是uvm_test_top,這個名字是由UVM在run_test時自動指定的。uvm_top的名字是__top__,但是在顯示路徑的時候,并不會顯示出這個名字,而只顯示從uvm_test_top開始的路徑。

2.

config_db機制用于在UVM驗證平臺間傳遞參數。它們通常都是成對出現的。set函數是寄信,而get函數是收信。如在某個測試用例的build_phase中可以使用如下方式寄信:

uvm_config_db#(int)::set(this, "env.i_agt.drv", "pre_num", 100);

其中第一個和第二個參數聯合起來組成目標路徑,與此路徑符合的目標才能收信。第一個參數必須是一個uvm_component實例的指針,第二個參數是相對此實例的路徑。第三個參數表示一個記號,用以說明這個值是傳給目標中的哪個成員的,第四個參數是要設置的值。

在driver中的build_phase使用如下方式收信:

uvm_config_db#(int)::get(this, "", "pre_num", pre_num);

get函數中的第一個參數和第二個參數聯合起來組成路徑。第一個參數也必須是一個uvm_component實例的指針,第二個參數是相對此實例的路徑。一般的,如果第一個參數被設置為this,那么第二個參數可以是一個空的字符串。第三個參數就是set函數中的第三個參數,這兩個參數必須嚴格匹配,第四個參數則是要設置的變量。

在之前的例子中,在top_tb中通過config_db機制的set函數設置virtual interface時,set函數的第一個參數為null。在這種情況下,UVM會自動把第一個參數替換為uvm_root::get(),即uvm_top。換句話說,以下兩種寫法是完全等價的:

initial beginuvm_config_db#(virtual my_if)::set(null, "uvm_test_top.env.i_agt.drv", "vif", input_if); end initial beginuvm_config_db#(virtual my_if)::set(uvm_root::get(), "uvm_test_top.env.i_ag t. drv", "vif", input_if); end

既然set函數的第一個和第二個參數聯合起來組成路徑,那么在某個測試用例的build_phase中可以通過如下的方式設置env.i_agt.drv中pre_num_max的值:

uvm_config_db#(int)::set(this.env, "i_agt.drv", "pre_num_max", 100);

因為前兩個參數組合而成的路徑和之前的寫法一致。

set函數的參數可以使用這種靈活的方式設置,同樣的,get函數的參數也可以。在driver的build_phase中:

uvm_config_db#(int)::get(this.parent, "drv", "pre_num_max", pre_num_max); 或者: uvm_config_db#(int)::get(null, "uvm_test_top.env.i_agt.drv", "pre_num_max", p re_num_max);

整個過程可以形象地這么去理解:

張三給李四寄了一封信,信上寫了李四的名字,這樣李四可以收到信。但是呢,由于保密的需要,張三只是在信上寫了“四”這一個字,只要張三跟李四事先約定好了,那么李四一看到上面寫著“四”的信就會收下來。

uvm_config_db#(int)::set(this, "env.i_agt.drv", "p_num", 100); uvm_config_db#(int)::get(this, "", "p_num", pre_num);

3.

假設在my_driver中有成員變量pre_num,其使用uvm_field_int實現field automation機制:

int pre_num; `uvm_component_utils_begin(my_driver)`uvm_field_int(pre_num, UVM_ALL_ON) `uvm_component_utils_end function new(string name = "my_driver", uvm_component parent = null);super.new(name, parent);pre_num = 3; endfunction virtual function void build_phase(uvm_phase phase);`uvm_info("my_driver", $sformatf("before super.build_phase, the pre_num is %0d", pre_num),super.build_phase(phase);`uvm_info("my_driver", $sformatf("after super.build_phase, the pre_num is %0d", pre_num),if(!uvm_config_db#(virtual my_if)::get(this, "", "vif", vif))`uvm_fatal("my_driver", "virtual interface must be set for vif!!!") endfunction

只要使用uvm_field_int注冊,并且在build_phase中調用super.build_phase(),就可以省略在build_phase中的如下get語句:

uvm_config_db#(int)::get(this, "", "pre_num", pre_num);

這里的關鍵是build_phase中的super.build_phase語句,當執行到driver的super.build_phase時,會自動執行get語句。這種做法的前提是:

  • 第一,my_driver必須使用uvm_component_utils宏注冊;
  • 第二,pre_num必須使用uvm_field_int宏注冊;
  • 第三,在調用set函數的時候,set函數的第三個參數必須與要get函數中變量的名字相一致,即必須是pre_num。

所以上節中,雖然說這兩個參數可以不一致,但是最好的情況下還是一致。李四的信就是給李四的,不要打什么暗語,用一個“四”來代替李四。

4.

在前面的所有例子中,都是設置一次,獲取一次。但是假如設置多次,而只獲取一次,即跨層次的多重設置時,UVM采用如下機制決定最終收到信息的內容,即:先看發信人,哪個發信人最權威就聽誰的,當同一個發信人先后發了兩封信時,那么最近收到的一封權威高,也就是發信人的優先級最高,而時間的優先級低。

假如uvm_test_top和env中都對driver的pre_num的值進行了設置,在uvm_test_top中的設置語句如下:

function void my_case0::build_phase(uvm_phase phase);super.build_phase(phase);uvm_config_db#(int)::set(this,"env.i_agt.drv","pre_num",999);`uvm_info("my_case0", "in my_case0, env.i_agt.drv.pre_num is set to 999",UVM_LOW)

在env的設置語句如下:

virtual function void build_phase(uvm_phase phase);super.build_phase(phase);uvm_config_db#(int)::set(this,"i_agt.drv","pre_num",100);`uvm_info("my_env", "in my_env, env.i_agt.drv.pre_num is set to 100",UVM_LOW) endfunction

那么driver中獲取到的值是100還是999呢?答案是999。UVM規定層次越高,那么它的優先級越高。這里的層次指的是在UVM樹中的位置,越靠近根結點uvm_top,則認為其層次越高。uvm_test_top的層次是高于env的,所以uvm_test_top中的set函數的優先級高。

上述結論在set函數的第一個參數為this時是成立的,但是假如set函數的第一個參數不是this會如何呢?假設uvm_test_top的set語句是:

function void my_case0::build_phase(uvm_phase phase);super.build_phase(phase);uvm_config_db#(int)::set(uvm_root::get(),"uvm_test_top.env.i_agt.drv","pre_num",999);`uvm_info("my_case0", "in my_case0, env.i_agt.drv.pre_num is set to 999", UVM_LOW)

而env的set語句是:

virtual function void build_phase(uvm_phase phase);super.build_phase(phase);uvm_config_db#(int)::set(uvm_root::get(),"uvm_test_top.env.i_agt.drv","pre_num",100);`uvm_info("my_env", "in my_env, env.i_agt.drv.pre_num is set to 100",UVM_LOW) endfunction

這種情況下,driver得到的pre_num的值是100。由于set函數的第一個參數是uvm_root::get(),所以寄信人變成了uvm_top。在這種情況下,只能比較寄信的時間。UVM的build_phase是自上而下執行的,my_case0的build_phase先于my_env的build_phase執行。所以my_env對pre_num的設置在后,其設置成為最終的設置。

假如uvm_test_top中set函數的第一個參數是this,而env中set函數的第一個參數是uvm_root::get(),那么driver得到的pre_num的值也是100。這是因為env中set函數的寄信人變成了uvm_top,在UVM樹中具有最高的優先級。

因此,無論如何,在調用set函數時其第一個參數應該盡量使用this。在無法得到this指針的情況下(如在top_tb中),使用null或者uvm_root::get()。

5.

關于同一層次的多重設置:

pre_num在99%的測試用例中的值都是7,只有在1%的測試用例中才會是其他值。

可以這么實現:

classs base_test extends uvm_test;function void build_phase(uvm_phase phase);super.build_phase(phase);uvm_config_db#(int)::set(this, "env.i_agt.drv", pre_num_max, 7);endfunction endclass class case1 extends base_test;function void build_phase(uvm_phase phase);super.build_phase(phase);endfunction endclass … class case99 extends base_test;function void build_phase(uvm_phase phase);super.build_phase(phase);endfunction endclass

但是對于第100個測試用例,則依然需要這么寫:

class case100 extends base_test;function void build_phase(uvm_phase phase);super.build_phase(phase);uvm_config_db#(int)::set(this, "env.i_agt.drv", pre_num_max, 100);endfunction endclass

case100的build_phase相當于如下所示連續設置了兩次:

uvm_config_db#(int)::set(this, "env.i_agt.drv", "pre_num", 7); uvm_config_db#(int)::set(this, "env.i_agt.drv", "pre_num", 100);

按照時間優先的原則,后面config_db::set的值將最終被driver得到。

6.

可以使用同配符設置config_db。

initial beginuvm_config_db#(virtual my_if)::set(null, "uvm_test_top.env.i_agt*", "vif", input_if); end

盡可能不要使用通配符*,盡量寫清楚,避免給同事添麻煩。

7.

用于connect_phase的check_config_usage可以顯示出截止到此函數調用時有哪些參數是被設置過但是卻沒有被獲取過,這可以用來檢查使用config_db時的第二個參數,即路徑字符串出錯的情況。

virtual function void connect_phase(uvm_phase phase);super.connect_phase(phase);check_config_usage(); endfunction

使用例子:

function void my_case0::build_phase(uvm_phase phase);uvm_config_db#(uvm_object_wrapper)::set(this,"env.i_agt.sqr.main_phase","default_sequence",case0_sequence::type_id::get());uvm_config_db#(int)::set(this,"env.i_atg.drv","pre_num",999);uvm_config_db#(int)::set(this,"env.mdl","rm_value",10); endfunction

仿真打印結果如下:

# UVM_INFO @ 0: uvm_test_top [CFGNRD] ::: The following resources have at least one write and no reads # default_sequence [/^uvm_test_top.env.i_agt.sqr.main_phase$/] : (class uvm_pkg::uvm_object_wrapper) # - # -------- # uvm_test_top reads: 0 @ 0 writes: 1 @ 0 ## pre_num [/^uvm_test_top.env.i_atg.drv$/] : (int) 999 # - # -------- # uvm_test_top reads: 0 @ 0 writes: 1 @ 0 #

上述結果顯示有兩條設置信息分別被寫過(set)1次,但是一次也沒有被讀取(get)。其中pre_num未被讀取是因為錯把i_agt寫成了i_atg。default sequence的設置也沒有被讀取,是因為default sequence是設置main_phase的,它在main_phase的時候被獲取,而main_phase是在connect_phase之后執行的。

8.

print_config函數用于config_db調試。其中參數1表示遞歸的查詢,若為0,則只顯示當前component的信息。它會遍歷整個驗證平臺的所有結點,找出哪些被設置過的信息對于它們是可見的。打印的信息大致如下:

# UVM_INFO @ 0: uvm_test_top [CFGPRT] visible resources: # <none> # UVM_INFO @ 0: uvm_test_top.env [CFGPRT] visible resources: # <none> # UVM_INFO @ 0: uvm_test_top.env.agt_mdl_fifo [CFGPRT] visible resources: # <none> … 參考自張強《UVM實戰》公眾號:程序員Marshall

總結

以上是生活随笔為你收集整理的uvm 形式验证_UVM基础的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

精品国产视频一区 | 天天干,天天操 | 久久国产精品一区二区 | 日韩激情影院 | 最近中文字幕高清字幕在线视频 | 色综合久久中文综合久久牛 | 国产一区二区三区在线免费观看 | 亚洲精品美女在线观看 | 久久av影视 | 九热在线| 在线只有精品 | 久草久草视频 | 又黄又爽的视频在线观看网站 | 91电影福利 | 国产成人精品一区二区三区免费 | 成年人在线观看免费视频 | 欧美成人按摩 | 日韩电影在线一区 | 精品国产一区二区三区av性色 | 日韩视频www | 啪啪av在线 | av一区在线 | 欧美 日韩 性| 日日综合 | 天天色天天综合 | 超碰国产97 | 久久国产网 | 91chinesexxx| 日韩精品网址 | 日韩免费在线观看 | 亚洲精品在线一区二区三区 | 在线电影a| 毛片网站在线 | 国产精品日韩精品 | 伊人色综合网 | 日韩欧美电影网 | 精品国产一区二区三区久久久久久 | 国产精品久久久久久久久久久久久 | 免费三级网 | 日韩激情中文字幕 | 亚洲电影第一页av | 日本少妇久久久 | 免费视频xnxx com| 99久久精品免费看国产四区 | 激情欧美在线观看 | 日韩av一区二区三区四区 | 在线小视频 | 中文字幕免费高清在线观看 | 中文字幕免费观看全部电影 | av日韩国产| 在线播放国产一区二区三区 | 777视频在线观看 | av电影一区二区三区 | 国产午夜三级一区二区三桃花影视 | 久草网在线视频 | 福利电影一区二区 | 国产精品麻豆视频 | 激情久久伊人 | 日韩在线观看一区二区三区 | 日韩国产欧美在线播放 | 天天干天天拍天天操 | 精品国产一区二区三区四区在线观看 | 日韩天天干 | 国产一区国产二区在线观看 | 99精品国产亚洲 | 操操日日 | 天天爱天天| 人人草在线视频 | 在线亚洲欧美日韩 | 夜夜高潮夜夜爽国产伦精品 | 麻豆91精品视频 | 综合影视 | 精品久久久成人 | 日韩欧美高清免费 | 免费日韩三级 | 国产黄在线观看 | 久久国产精品色av免费看 | 99资源网| 中文超碰字幕 | 99精品网站 | 园产精品久久久久久久7电影 | 天天色天天艹 | 成人av在线亚洲 | 99国产精品一区二区 | 国产精品自产拍在线观看中文 | 91麻豆精品国产自产在线 | 日本99干网 | www.av免费观看 | av网址在线播放 | 国产精品国产三级在线专区 | 最新精品视频在线 | 国产首页 | 精品国产欧美一区二区 | 精品免费视频. | 在线中文字幕网站 | 成人蜜桃网| 91精品人成在线观看 | 日本黄色a级大片 | 久久综合狠狠综合久久狠狠色综合 | 国产黄色精品视频 | 日韩在线视频线视频免费网站 | 久久久午夜精品理论片中文字幕 | 在线综合 亚洲 欧美在线视频 | 国际精品久久 | 97超碰超碰久久福利超碰 | 国产毛片久久 | 黄色不卡av| 亚洲涩涩涩涩涩涩 | 成人黄色大片在线免费观看 | 亚洲区另类春色综合小说校园片 | 国产精品99视频 | 人人讲 | 丁香久久久 | 国产成人一区在线 | 99精品偷拍视频一区二区三区 | 亚洲一区二区观看 | 免费在线观看毛片网站 | 欧美另类69 | 久久视频国产精品免费视频在线 | 婷婷色六月天 | 亚洲一级片 | 亚洲精品乱码久久久久久蜜桃动漫 | 99热最新在线 | 日本韩国欧美在线观看 | 九九九热视频 | 在线看欧美 | 四虎免费在线观看 | 在线观看日韩国产 | 国产精品a久久 | 在线观看精品一区 | 欧美二区视频 | 婷婷中文字幕综合 | 国产专区在线 | a黄色影院 | 日韩免费一区二区在线观看 | 国产精品久久久久久久久久久久午夜 | 欧美精品久久久久久久亚洲调教 | 日韩在线免费小视频 | 国产精品普通话 | 午夜精品福利在线 | 中文字幕在线看视频 | 精品国产免费久久 | 亚洲成人一二三 | 黄色a视频 | 亚洲视频在线观看免费 | 国产亚洲午夜高清国产拍精品 | 久久精品99久久久久久 | 国产午夜一区二区 | 一区二区三区在线观看中文字幕 | www.夜色.com | 91成人精品视频 | 亚洲九九精品 | 日韩最新av | 色综合夜色一区 | 九九视频精品在线 | 色综合天天视频在线观看 | 日韩视频在线观看视频 | 亚洲精品国偷拍自产在线观看蜜桃 | 成人三级av | 国产精品不卡在线 | 国产午夜三级一区二区三桃花影视 | 91免费看黄 | 国产 欧美 日本 | 亚洲日韩欧美一区二区在线 | 99产精品成人啪免费网站 | 国产精品美女免费 | 国产精品女人久久久 | 亚洲国产精品传媒在线观看 | 中文字幕在线观看第二页 | 欧美91视频 | 中文字幕在线看人 | 国产一区视频在线观看免费 | 日韩精品视频免费看 | 欧美亚洲成人xxx | 九九视频这里只有精品 | 久久综合久色欧美综合狠狠 | 欧美一区中文字幕 | 国产精品乱码久久久久 | 欧洲黄色片 | 中文字幕一区二 | 免费情趣视频 | 天天操操操操操 | 久久久久亚洲精品中文字幕 | 中文字幕丝袜一区二区 | 国产成人在线观看 | 久草资源免费 | 久久在线观看视频 | 一区二区激情 | 毛片一区二区 | 激情av资源网 | 亚洲成色777777在线观看影院 | 最近日本字幕mv免费观看在线 | 996久久国产精品线观看 | 亚洲在线精品视频 | 久久国产精品一区二区三区四区 | 日韩理论在线播放 | 久久99国产精品自在自在app | 亚洲国产成人精品在线 | av女优中文字幕在线观看 | 久久久久亚洲精品国产 | 天天摸夜夜操 | 久久天堂亚洲 | 97手机电影网 | 色婷婷精品大在线视频 | 九九热99视频 | 蜜臀久久99精品久久久久久网站 | 97精品欧美91久久久久久 | 成人黄性视频 | 免费观看一级成人毛片 | 在线 你懂 | 日韩欧美大片免费观看 | 欧美日韩在线观看一区二区三区 | 又黄又刺激又爽的视频 | 久草在线观看视频免费 | 999成人| av千婊在线免费观看 | 婷婷av电影 | 久久久成人精品 | 欧美成人高清 | 五月婷在线观看 | 久久国产电影 | 亚洲成人精品在线观看 | 免费黄色在线网站 | 青草视频在线看 | 天天看天天干天天操 | 久久精品视| 婷婷综合av | www免费看片com | 91高清一区 | 91爱爱免费观看 | 国产又粗又猛又爽又黄的视频免费 | 91少妇精拍在线播放 | 国产精品美女久久久 | 久久国产精品久久精品国产演员表 | 欧美另类一二三四区 | 久草视频国产 | 六月丁香伊人 | 欧美色888 | 欧美性天天 | 国产一区二区三区黄 | 欧美精品久久久久久久免费 | 日韩精品免费一区二区 | 中文在线www | 欧美日本不卡高清 | 五月天婷婷在线观看视频 | 色综合天天狠天天透天天伊人 | 久久99九九99精品 | 午夜少妇一区二区三区 | 久草在线电影网 | 亚洲国产精品99久久久久久久久 | 狠狠的干狠狠的操 | 精品国产一区二区三区久久久蜜月 | 精品久久久久久电影 | 精品a在线 | 午夜视频在线观看一区 | 国产裸体永久免费视频网站 | 久久人人爽人人 | 久久不卡日韩美女 | 69精品视频在线观看 | 夜夜躁狠狠燥 | 亚洲激情久久 | 免费看三级黄色片 | av在线播放中文字幕 | 亚洲一二区精品 | 欧美调教网站 | 黄色a级片在线观看 | av免费在线观看网站 | 亚洲精品国产电影 | 973理论片235影院9 | 色中文字幕在线观看 | 色婷婷久久久综合中文字幕 | 国产一区麻豆 | 国产一区二区日本 | 国产精品久久久一区二区 | 日韩中文在线播放 | 五月天久久 | 91天堂在线观看 | 亚洲精品色视频 | 国产国语在线 | 欧美日韩不卡一区二区三区 | 日韩精品一区二区三区在线视频 | 久久久久久久久久久国产精品 | 日韩久久久久久 | 精品久久久久亚洲 | 国产一级91| 99精品一区二区三区 | 国产精品久久久一区二区 | 国产日韩精品在线观看 | 深爱激情五月综合 | 手机色站| 国产精品嫩草影视久久久 | 菠萝菠萝蜜在线播放 | 天天操天天是 | 欧美精品免费在线观看 | 亚洲高清视频一区二区三区 | www.91av在线 | 综合久久精品 | 欧美日韩国产一二 | 天天爱天天射天天干天天 | av网站在线观看播放 | 亚洲一级电影在线观看 | 久久久精品网站 | www.福利视频 | 精品主播网红福利资源观看 | 韩国一区二区三区视频 | 久久久99精品免费观看乱色 | 在线一区观看 | 免费合欢视频成人app | 91污在线观看 | 国产精品99久久久久久有的能看 | 精品国产理论片 | 三级av网站 | 婷婷激情五月综合 | 久草在线免费看视频 | 不卡视频在线看 | 国产在线一线 | 免费在线观看国产精品 | 亚洲国产成人高清精品 | 天天干天天拍天天操 | 国产亚洲视频中文字幕视频 | 国产午夜三级一二三区 | 天天爱综合 | 国产一区二区三区免费在线观看 | 国产区在线看 | 日日爽视频 | 国产成人精品一区二区在线观看 | 亚洲精品在线视频网站 | 亚洲国产欧美在线人成大黄瓜 | 99久久99久久综合 | 日韩在线观看视频网站 | 精品资源在线 | 一区二区三区精品在线视频 | 欧美日韩在线视频一区 | 久久夜色精品国产欧美乱 | 精品亚洲va在线va天堂资源站 | 久久99久久久久久 | 激情av网 | 午夜av日韩| 亚洲砖区区免费 | 国产麻豆视频网站 | 久久久久综合精品福利啪啪 | 精品国模一区二区三区 | 夜夜夜夜猛噜噜噜噜噜初音未来 | 国产日产高清dvd碟片 | 97成人免费视频 | 亚洲97在线 | 国产精品手机播放 | 国产精品一区二区免费看 | 久久国产精品视频 | 一级黄色视屏 | 免费的成人av | 99精品视频免费 | 日韩一级精品 | 亚洲精品国久久99热 | 中文字幕一区二区三区精华液 | 国产精品美女久久久久久 | 国产免费一区二区三区最新6 | 97视频在线观看网址 | 波多野结衣视频一区二区三区 | 日韩在线视频观看免费 | 中文字幕免费看 | 成人午夜毛片 | 国产传媒一区在线 | 日韩电影在线看 | 成人三级黄色 | 国产精品一区二区免费视频 | 国产精品 欧美 日韩 | 国产精品九九九 | 日韩大片在线免费观看 | 国产99久久久精品 | 超碰在线人人 | 91超碰在线播放 | 一级国产视频 | 人人插人人费 | 超碰在线观看97 | 精品久久久国产 | 91看片淫黄大片一级在线观看 | 免费观看mv大片高清 | 丝袜美腿亚洲 | 500部大龄熟乱视频 欧美日本三级 | 91av看片 | 337p西西人体大胆瓣开下部 | 日韩av成人在线观看 | 久久精品国产免费看久久精品 | 夜夜视频欧洲 | 欧美色图另类 | 国产精品一区二区av日韩在线 | 很污的网站 | 亚洲高清精品在线 | 国产一级电影网 | 亚洲国产97在线精品一区 | 成人在线观看资源 | 国产亚洲欧美一区 | 国产欧美精品在线观看 | 免费视频久久久 | 麻豆久久久久久久 | 久草视频在线新免费 | 日韩电影一区二区三区 | 欧美性生活免费看 | 9999国产| 91av片 | 国产在线精品福利 | 国产精品igao视频网网址 | 国产伦理久久精品久久久久_ | 在线成人一区二区 | 久久亚洲在线 | 国产中文字幕第一页 | 久久精品国产久精国产 | 中文字幕中文字幕在线中文字幕三区 | 久久久国产精华液 | 日韩高清三区 | 久久久久久久久久伊人 | 日本乱视频 | 成人午夜电影久久影院 | 波多野结衣在线中文字幕 | 91福利视频久久久久 | 日日爱999| 亚洲理论片 | 色老板在线| 日韩欧美在线第一页 | 91成人久久 | 美女视频久久久 | 欧美aa在线观看 | 欧美成人xxx| 亚洲人成综合 | 国产精品久久嫩一区二区免费 | 久久99国产精品自在自在app | 日韩欧美电影在线 | 日韩在线播放av | 精品你懂的| 午夜精品久久久久久久久久久久久久 | 五月婷婷色丁香 | 国产精品日韩在线播放 | 天天拍天天色 | 国产视频精品免费 | 久久久久免费精品国产小说色大师 | 日本久久久精品视频 | 成人免费 在线播放 | 日韩精品免费一线在线观看 | av电影一区二区 | 天天鲁天天干天天射 | 久久不见久久见免费影院 | 亚洲九九九 | www色 | 成人91免费视频 | 99tvdz@gmail.com | 国产精品亚洲综合久久 | 中文字幕视频一区 | 免费网站黄 | 精品自拍sae8—视频 | av在线不卡观看 | 亚洲精品美女久久17c | 色九九影院 | 四虎影视av| 狠狠干免费 | 久久久久久看片 | 亚洲人视频在线 | 日韩精品综合在线 | 日韩精品国产一区 | 亚洲视频免费在线看 | www五月天婷婷 | 黄色一级大片在线免费看国产一 | 午夜精品电影 | 国产高清成人av | 51久久夜色精品国产麻豆 | 婷婷丁香久久五月婷婷 | 黄色三级免费看 | 在线观看一级视频 | 91精品国产乱码久久桃 | 久视频在线 | 伊甸园永久入口www 99热 精品在线 | 国产精品久久电影网 | 999在线精品 | 日韩两性视频 | 欧美成人精品三级在线观看播放 | 91视频传媒 | 日日操天天操夜夜操 | 日韩com | 激情欧美一区二区免费视频 | 日韩电影中文,亚洲精品乱码 | 午夜在线观看一区 | 久久少妇av | 久要激情网| 天天色天天操综合网 | 欧美精品乱码久久久久久 | 国产在线精品福利 | 久久久久亚洲a | 国产一二区免费视频 | 91色一区二区三区 | 亚洲精品国产片 | 国产亚洲高清视频 | 国产精品久久久久久久久久东京 | 国产一线天在线观看 | 国产一级视频在线观看 | 伊人精品在线 | 超碰成人av| 欧美做受高潮 | 国产精品99在线观看 | 免费国产一区二区视频 | 最新精品视频在线 | 欧美激情综合色综合啪啪五月 | 毛片一级免费一级 | 五月天久久婷 | 91精品国产91久久久久福利 | 久久国产精彩视频 | 国产精品99久久免费黑人 | 美女视频永久黄网站免费观看国产 | 91视频xxxx| 在线黄色国产电影 | 欧美久久久久久久久久久久 | av网在线观看 | 精品一区二区三区久久久 | av免费电影在线 | 91在线播 | 狠狠黄| 深爱开心激情网 | 色资源二区在线视频 | 正在播放一区二区 | 国产精品成人在线 | 久久久精品亚洲 | 99精品视频免费观看视频 | 国产vs久久 | 午夜男人影院 | 国产精品美女久久久 | 欧美精品中文字幕亚洲专区 | 韩日av一区二区 | 91成人精品一区在线播放69 | 中文字幕成人在线观看 | 天天综合五月天 | 国产精品入口麻豆www | 天天综合天天做天天综合 | 狠狠色狠狠色合久久伊人 | 久久6精品 | 五月天电影免费在线观看一区 | 久久电影网站中文字幕 | 在线免费视频你懂的 | 在线色吧| 日韩综合在线观看 | 久久久久色| 国语久久 | 日韩精品一区二区三区在线视频 | 在线视频a | 久久99视频精品 | 91精品在线免费视频 | 91麻豆免费视频 | 韩日电影在线免费看 | 久操视频在线免费看 | 国产精品刺激对白麻豆99 | 国产麻豆精品95视频 | 国产色中涩 | 国产精品久久久 | 国产精品视频免费在线观看 | 成人影视免费 | 欧美一区二区三区免费看 | 精品美女久久久久久免费 | 91久久人澡人人添人人爽欧美 | 黄网站色 | 国产成人精品亚洲日本在线观看 | 国产精品免费视频网站 | 国产一级二级在线播放 | 日日碰狠狠添天天爽超碰97久久 | 亚洲三级性片 | 久久av影院 | 国产一级视频在线 | 深夜国产福利 | 国产99久久久欧美黑人 | 97视频久久久| 久久久久高清 | 久久久久久久久久网站 | 亚洲成人av片 | 五月婷婷久久丁香 | 亚洲欧美在线综合 | 伊人视频| 久久avav| 久久久久久久久久影院 | 99久高清在线观看视频99精品热在线观看视频 | 亚洲高清久久久 | 99精品视频免费全部在线 | 国产成人一区三区 | 国产精品麻豆免费版 | 在线精品亚洲一区二区 | 久久精品站 | 91精品在线观看入口 | 97视频免费 | 激情五月播播久久久精品 | 美女黄网站视频免费 | 精品美女久久久久久免费 | 国产欧美日韩一区 | 97自拍超碰| 波多野结衣一区 | 在线观看日韩精品视频 | 人人射av | 久久久精品国产一区二区电影四季 | 日韩超碰在线 | 久久亚洲福利视频 | 国产性天天综合网 | 91九色国产在线 | 免费观看一级视频 | 性色视频在线 | 综合网欧美 | 91精品在线免费观看视频 | 成人午夜精品 | 国产美女在线观看 | 99国产精品视频免费观看一公开 | 天天操天天爱天天爽 | 狠狠躁日日躁夜夜躁av | 高清av免费看 | 密桃av在线 | 中文字幕精品在线 | www.天天射.com| 亚洲欧洲xxxx | 91成人欧美| 国内精品久久久久久久久久 | 99久久99久久精品免费 | 国产91精品在线播放 | 国产亚洲欧美日韩高清 | 成人精品视频 | 久久久久国产免费免费 | 狠狠综合久久 | 91成人在线观看高潮 | 国产精品久久久久久欧美 | www狠狠操| 在线免费av播放 | 亚洲开心激情 | av在线播放免费 | 亚洲一区二区黄色 | 久久一区二区三区日韩 | 九九热在线视频免费观看 | 国产九九在线 | 亚洲精品男人的天堂 | 激情小说久久 | 最近免费观看的电影完整版 | 欧美色综合天天久久综合精品 | 91免费日韩 | 久草久视频 | 国产麻豆精品传媒av国产下载 | 欧美美女一级片 | 深爱激情五月婷婷 | 免费看av在线 | www五月天| 2021国产在线 | 国产精品一区二区62 | 国产字幕av | 大型av综合网站 | 91视频免费观看 | 999电影免费在线观看2020 | 黄色a视频 | 在线视频 你懂得 | 日韩欧美69 | 国产高清视频在线观看 | 首页av在线 | 亚洲精品日韩在线观看 | 最近中文字幕免费av | 亚洲在线视频观看 | 91福利在线观看 | 精品国产乱码久久久久久1区2匹 | 久久久久久久久久久久av | 免费看国产曰批40分钟 | 亚洲精品在线观看av | 欧美一性一交一乱 | 色综合久久久久久久久五月 | 日韩四虎 | 岛国大片免费视频 | 亚洲干视频在线观看 | 午夜电影 电影 | 久久成人高清视频 | 天天做天天干 | 丝袜美女在线观看 | 免费的黄色的网站 | 五月天婷婷在线播放 | 91传媒免费在线观看 | 精品99视频 | 在线免费观看黄色av | 97爱爱爱| 亚洲精品免费在线观看视频 | 九九精品视频在线观看 | 亚洲欧美日本A∨在线观看 青青河边草观看完整版高清 | 青草视频网 | 午夜电影久久久 | 手机av在线网站 | 91看片淫黄大片91 | 麻豆你懂的| 97久久精品午夜一区二区 | 国产黄色精品视频 | 欧美日韩不卡一区二区 | 久久久69 | 欧美高清视频不卡网 | 国产999视频在线观看 | 日韩亚洲国产精品 | 亚洲一区二区三区毛片 | 久久精品国产久精国产 | 亚洲精品国产成人av在线 | 狠狠操欧美| 日韩三区在线观看 | 一级成人在线 | 国产尤物在线观看 | 美女中文字幕 | 成人毛片在线观看视频 | 98涩涩国产露脸精品国产网 | 午夜精品一区二区三区视频免费看 | 精品高清视频 | 国产精品美女久久久久久久久 | 亚洲精品视频网站在线观看 | 免费看毛片在线 | 91pony九色丨交换 | 国产黄色高清 | 91午夜精品| 国产一区在线视频 | 欧美激情精品久久久久久免费 | 国产福利电影网址 | 偷拍区另类综合在线 | 日韩av电影手机在线观看 | 久草精品在线观看 | 亚洲久草网| 亚洲丝袜一区二区 | 日韩免费视频播放 | 国产一区二区三区免费观看视频 | 午夜精品一区二区三区在线视频 | 成人免费视频网址 | 中文字幕在 | 久久久久久久久久久久久久免费看 | 亚洲激精日韩激精欧美精品 | 99精品在线播放 | 欧美亚洲精品一区 | 国产欧美最新羞羞视频在线观看 | 亚洲 欧美日韩 国产 中文 | 狠狠色狠狠色综合日日小说 | 亚洲国产精品999 | 91在线视频观看 | 国产精品白丝av | 免费黄色网止 | 久久爱综合 | 人人插超碰 | 视频在线91| 色99之美女主播在线视频 | www色com| 国产美女免费 | 91片黄在线观 | 国产免费亚洲 | 操少妇视频 | 久久艹在线观看 | h文在线观看免费 | 国产a国产 | 亚洲精品视频一 | 国产va精品免费观看 | 日日操日日插 | 亚洲国产福利视频 | 亚洲欧美综合精品久久成人 | 久久极品 | 亚洲精品国产电影 | 99精品视频免费观看 | 右手影院亚洲欧美 | 日韩在线观看中文 | 欧美电影黄色 | 色吧久久 | bayu135国产精品视频 | 探花视频在线观看免费版 | 国产va在线 | 二区中文字幕 | 91网在线观看 | 国产手机视频在线观看 | 在线免费观看的av网站 | 国产精品久久久久久久久搜平片 | 亚洲涩涩涩涩涩涩 | 日韩久久久久久久久久 | 日精品在线观看 | av成人免费在线看 | 国产一卡二卡四卡国 | 手机在线中文字幕 | 黄色成人小视频 | 三级在线国产 | 国产精品久久久一区二区 | 久久中文字幕导航 | 日韩精品在线免费观看 | 成人九九视频 | 欧美激情精品久久久久久免费 | 最新中文字幕在线资源 | 日韩精品在线看 | 中文字幕资源网 国产 | 国产精品一区二区三区四 | 蜜臀av免费一区二区三区 | 一区二区不卡 | 日本中文字幕一二区观 | 国产精品99页 | 免费在线观看不卡av | 天天干,夜夜操 | 精品一区二区三区香蕉蜜桃 | 欧美亚洲专区 | 波多野结衣精品视频 | x99av成人免费 | 国产中文字幕在线 | 欧美一级日韩免费不卡 | 久久天天躁狠狠躁亚洲综合公司 | 五月天精品视频 | 久热免费在线观看 | 国内精品久久久精品电影院 | 国产精品久久久久久久久久久久久 | 香蕉视频在线视频 | 精品久操| 色综合天天做天天爱 | 这里有精品在线视频 | av大片免费 | 亚洲夜夜网| 亚洲精品小视频 | 九九热视频在线播放 | 成 人 黄 色 免费播放 | 日韩欧美网站 | 亚洲午夜久久久久久久久电影网 | 国产一区在线免费观看视频 | 91九色在线视频观看 | 高清精品在线 | 中文字幕电影高清在线观看 | 亚洲成av片人久久久 | 国产毛片在线 | 2021国产精品 | 亚洲成人av电影在线 | 最新av网址在线 | 97超碰人 | 日韩精品久久久久久久电影竹菊 | 国产精品午夜在线观看 | 91亚洲精品久久久久图片蜜桃 | 日韩欧美视频在线免费观看 | 成人午夜精品福利免费 | 国产99久久99热这里精品5 | 91精品视频在线免费观看 | 亚洲免费在线观看视频 | 久久久久综合 | 亚洲欧美999 | 成人在线播放免费观看 | av中文天堂在线 | 日韩有码中文字幕在线 | 在线国产视频一区 | 国产在线日本 | 欧美电影在线观看 | 在线观看日本韩国电影 | 一区二区三区韩国免费中文网站 | 中文字幕欲求不满 | 波多野结依在线观看 | 成x99人av在线www| 97视频网址| 色福利网 | 免费国产在线视频 | 九九热在线精品 | 黄色一级大片在线观看 | 国产一级片免费视频 | 亚洲伊人av | 亚洲视频 一区 | 2018亚洲男人天堂 | 久久综合中文字幕 | 91精品一区二区在线观看 | 91色国产在线| 国产成人av电影在线 | 欧美日韩性视频 | 国产午夜激情视频 | 最新日韩在线 | 日本亚洲国产 | 黄色网在线播放 | 欧美日韩aaaa | 日本护士三级少妇三级999 | 不卡的av电影在线观看 | 亚洲一区二区三区91 | 天天爱天天插 | 日韩一区二区三区视频在线 | 一区二区视频在线播放 | av3级在线| 久久成人综合视频 | 欧美 亚洲 另类 激情 另类 | 国产精品久久毛片 | 亚洲美女精品 | 国产区免费 | 激情久久伊人 | 亚洲国产欧美在线人成大黄瓜 | 一区二区视频网站 | 日本久久久久久久久久久 | 日韩精品一区二区三区不卡 | 亚洲精品高清在线 | 亚洲视频一级 | 91麻豆精品国产91久久久无限制版 | 日韩在线视频一区二区三区 | 精品国产一区二区三区久久久蜜月 | 国产激情小视频在线观看 | 国产亚洲精品日韩在线tv黄 | 国产手机视频在线播放 | 999久久a精品合区久久久 | 日韩美女av在线 | 亚洲在线成人精品 | 一区二区三区av在线 | 国产xvideos免费视频播放 | 国产99久久久国产精品免费二区 | 色插综合 | 三级在线播放视频 | aⅴ视频在线| 日韩免费电影一区二区 | 欧美黑人性爽 | 毛片.com| 国内精品国产三级国产aⅴ久 | 在线视频a | 日韩在线观看视频中文字幕 | 日韩黄色一区 | 一区二区观看 | 在线观看中文字幕视频 | 99热精品在线观看 | 成人午夜免费福利 | 狂野欧美激情性xxxx | 97网站| 色综合天天色 | 欧美日韩天堂 | 91在线文字幕 | 亚洲综合在线五月天 | 81国产精品久久久久久久久久 | 97精品国产97久久久久久 | 中文字幕在线影视资源 | 国产va精品免费观看 | 久久久久久久久毛片精品 | 黄色一级片视频 | 在线观看视频黄色 | 久久精品国产精品亚洲精品 | 国产精品视频在线看 | 天天操天天色天天 | 超碰资源在线 | 久久美女免费视频 | 国产裸体视频网站 | 超碰免费观看 | 网站在线观看你们懂的 | 亚洲第一区在线观看 | 国产一区欧美一区 | 91视频链接 | 久草a在线| 91精品在线麻豆 | 狠狠干狠狠操 | 亚洲黄色免费 | 亚洲无毛专区 | 午夜三级影院 | 国产馆在线播放 | 九九九在线观看视频 | 国产毛片在线 | 丁香五月亚洲综合在线 | 国产午夜精品在线 | 久久免费99精品久久久久久 | 日韩免费网址 | 伊人狠狠色丁香婷婷综合 | 久章草在线观看 | 91精品啪 | 91免费网址 | 久久精品—区二区三区 | 亚洲精品乱码久久久久久蜜桃不爽 | 国产99在线 | 国产日韩在线视频 | 久久呀 | av永久网址 | 国产视频观看 | 国产精品扒开做爽爽的视频 | 超碰成人免费电影 | 久久艹艹| 亚洲国产日韩一区 | 美女国产免费 | 亚洲国产影院 | 亚洲涩涩涩 | 亚洲.www | 日韩电影精品一区 | 日韩欧美在线不卡 | 久久小视频| 五月婷在线视频 | 国产午夜精品理论片在线 | 999在线视频 | 中文在线a天堂 | 91在线中文| 超碰激情在线 | 亚洲电影毛片 | 久久久免费看 | 国产午夜精品理论片在线 | 国产精品你懂的在线观看 | 麻花豆传媒一二三产区 | 日本精品视频免费观看 | 免费精品 | 91视频三区| 国产精品伦一区二区三区视频 | 在线观看一区视频 | 国产精品久久久久久久久久久免费 | 日韩精品久久久久久久电影99爱 | 国产精品自在线拍国产 | 日韩二三区| 在线看毛片网站 | 成人三级网址 | 99欧美视频 | 国内小视频在线观看 | 久久国产精品一区二区三区四区 | 999久久国产精品免费观看网站 | 亚洲电影久久 | 欧美精品v国产精品v日韩精品 | 欧美91片| 成人av中文字幕在线观看 | 国产99久久久精品 | 国产精品久久久久影视 | 久久精品久久久久电影 | 男女男视频 | 日本黄色免费在线 | 日韩一区正在播放 |