一些uvm的学习体会

好久没用博客园来,虽然以前也几乎没怎么用,但还是想慢慢用来,最近在学习uvm,一些心得体会,比较浅显的认识,但还是希望记录下来。

 

 

 现有验证平台基本上都是基于VHDL完成的,验证工作通过的流程基本如下:

    1.根据描述学习验证代码实现功能

    2.制定Testing计划,根据功能要求提出关键性的feature,每条case针对一种或几种feature(相当于定向测试)

    3.针对DUT完成验证平台的搭建,这一步通常是各自完成,但是由于很多case比较类似,因此相互之间很多可以借鉴共享,但是每条case的DUT都有一定的针对性。

    4.验证功能,寻找Bug,对实现功能不清楚的地方和设计一起check,最后所有case测试完成以后进行review,看有没有需要进一步改进并测试的地方。

 

  所以基本上现在的工作中没有用到方法学中的那套东西,这类测试平台搭建有其优点:

    1.比较容易理解,因为从结构上而言,和设计级别的代码没有太多区别,抽象级别并不是很高,所以可以比较容易的从模块的互联互通上了解整个平台实现的功能。

    2.针对性比较强,针对不同feature的平台搭建有复杂又简单,对于简单的测试内容,搭建测试平台较为容易。

    3.测试更接近设计,平台的搭建自底向上,一般可以便搭建平台便查看DUT波形,通过最直接的波形来完成平台的搭建,保证所完成的case不会因为平台产生过多问题。

 

  但是,这样的方式也是问题多多,首先,平台通用性比较差,尽管在实际工作中,已经将各类功能一定程度上抽象出来,代码可以实现重用,但是毕竟封装的层次有限,用户可以很容易对代码进行一定修改(可以比较容易实现特定功能,但是为后期维护带来麻烦)。同时,使用VHDL进行一些验证功能实现的时候,实现一些常用功能较为麻烦,很多时候需要像设计一个模块一样对待一个功能的设计,而且,会花费很多精力在模块的互联上,等等。

  之前也查找过适用于VHDL的方法学,简单了解了一下,使用了其中很小一部分功能(生成随机数),但是在使用中还是发现很多不太方便的地方,最直接的问题是,在VHDL中package的申明和调用关系比较严格,编译时候必须严格按照包涵的次序,不然很容易报错。其次,查看源码后发现之前使用的那个随机功能其实也较弱,因此,并没有太深入的去了解下去。

  最近工作比较闲,决定花点时间好好研究一下现在流行的方法学,看看能否给自己今后的工作带来一些启发。其实之前同事就推荐过UVM,不过并没有花精力去好好了解一下,毕竟,我本身没有systemverilog的基础,所以一直有些望而却步。下定决心后,花了几天时间泛读了一下《Systemverilog验证/测试平台编写指南》这本书,感受最深的是OOP以及为覆盖率的概念。个人的感受是,如果没有通过C++或是JAVA这类软件语言学习过OOP,而是从verilog到systemverilog,对于OOP的理解可能会费力一些,我的理解是,systemverilog毕竟是通过借鉴软件语言的方式来扩展verilog,而verilog本质上又不是编程语言(硬件描述语言),所以systemverilog总给我一种依葫芦画瓢的感觉,好用,但是有些变扭。我觉得sv得到业界大力支持的地方首先是他在硬件描述方面的能力,得益于verilog,其次是对软件工程上OOP概念的借鉴,可以完成复杂功能设计。

  站在高一点的角度说,作为验证,特别是系统级别的验证,其实非常接近于软件层面,testbench要完成软件之于硬件的工作,又要能对硬件的功能信号进行分析,实现这样的方法有很多,就目前工作中使用的方式是VHDL加上C++进行系统级的仿真,其之间通过FLI接口进行交互。使用编程语言的好处是,仿真环境更接近真实,但是调试过程比较费劲,因为整个环境的运行需要modelsim以及GCC联合进行,中间通过动态链接库交换信息,如果想要对硬件环境进行干预的话比较麻烦,最终的debug方式往往只能通过C语言运行平台打印出来的信息进行判断,而且仿真的时间比较漫长,50ms的过程需要仿真数小时。其中,对硬件的干预能力弱是一个主要问题。作为systemverilog,其编写的方式更加软件化,又不失硬件语言的本质,因此成为业界主流的验证语言也就顺理成章了。

  在学习UVM中,我觉得其实对于整个UVM验证平台的结构组成上,理解起来并不是太费劲,一般典型的结构就如下图所示那样(图片来源:UVM1.1应用指南及源码分析)

一些uvm的学习体会_第1张图片

而简单的验证平台可能只包含driver、monitor甚至连reference model和scoreboard都没有,完全通过人力去比对,想想就感觉非常蛋疼。这也是为什么我非常想学习UVM的原因。UVM对于整个验证平台的分门别类,可以让我非常轻松的搭建起一个具有完整功能的平台,也避免了大家重复造轮子。

 

  这样归类以后,验证平台的顶层就变成了下面这个样子,短短几十行内容,而具体的东西,例如,dut与平台间的互联互通、业务的生成、数据的比对工作等,就分散到了最顶上include进来的各个模块中,使用和修改起来都非常方便。

(代码来源:UVM实战)

`timescale 1ns/1ps
`include "uvm_macros.svh"

import uvm_pkg::*;
`include "my_if.sv"
`include "my_transaction.sv"
`include "my_driver.sv"
`include "my_monitor.sv"
`include "my_agent.sv"
`include "my_model.sv"
`include "my_scoreboard.sv"
`include "my_env.sv"

module top_tb;

reg clk;
reg rst_n;
reg[7:0] rxd;
reg rx_dv;
wire[7:0] txd;
wire tx_en;

my_if input_if(clk, rst_n);
my_if output_if(clk, rst_n);

dut my_dut(.clk(clk),
           .rst_n(rst_n),
           .rxd(input_if.data),
           .rx_dv(input_if.valid),
           .txd(output_if.data),
           .tx_en(output_if.valid));

initial begin
   clk = 0;
   forever begin
      #100 clk = ~clk;
   end
end

initial begin
   rst_n = 1'b0;
   #1000;
   rst_n = 1'b1;
end

initial begin
   run_test("my_env");
end

initial begin
   uvm_config_db#(virtual my_if)::set(null, "uvm_test_top.i_agt.drv", "vif", input_if);
   uvm_config_db#(virtual my_if)::set(null, "uvm_test_top.i_agt.mon", "vif", input_if);
   uvm_config_db#(virtual my_if)::set(null, "uvm_test_top.o_agt.mon", "vif", output_if);
end

endmodule

 

 

下面一个是我使用vhdl编写的测试平台代码,某些部分由于利益关系已经隐去,看一下大致的实现就好。

可以看到整个测试平台的代码非常庞大,节凑层次并不是很清晰,看起来比较费劲。

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_textio.all;
use ieee.numeric_std.all;
library std;
use std.textio.all;
use ieee.std_logic_misc.all;

use ieee.math_real.all;
library c;
use c.stdio_h.all;

use work.tb_***_pkg.all;


library ??????????????;
use ????????????.data_type_package.all;



--------------------------------spec of testcase----------------------------------------------------------------------------------------
--basic structure for mutlti channel case:
--
--gen indivual prbs block for each *** channel
-- _________     __   
--|         |==>|  \                                                                  ___________________
--|__prbs1__|<==|   \ <-----------prbs_gen_sel---------------------------------------|__regular_pkt_send__|
-- _________    |    \                                         _______________________        ||
--|         |==>|     |<----------prbs_chk_sel----------------|__regular_pkt_receive__|       ||                                            
--|__prbs2__|<==| 12  |                                                   /\                  ||
-- _________    | chan|                                           ________||_________________ \/_____
--|         |==>| sel |                         ___________      |                                   |
--|__prbs3__|<==|     |===prbs_gen_dout_sel===>|           |     |                                   |
--     .        |     |<==prbs_chk_din_sel=====|????? rx&tx|<===>|                DUT                |
--     .        |     |                        |___________|     |___________________________________|
--     .        |     |
-- _________    |    /
--|         |==>|  /
--|__prbs12_|<==|/


   

------------------------------------------------------------------------------------------------------------------------




entity testcase1012xxx12345_&&& is 
 generic (
    channel_number :integer :=12
  );
end testcase1012xxx12345_&&&;

architecture sch of testcase1012xxx12345_&&& is

component xxx12345_&&&
  generic (
    ###_enable           : integer := 1;  --1: use ### interface  ,0  use ????? interface in FE mode
    channel_number       : integer := 12;
    max_channel_id       : integer := 20;
    ethernet_head_length : integer := 23  --WDM *** over ethernet protocal
    );
  port
    (
      clkUnknow_reset_l  : in  std_logic;
      clkUnknow          : in  std_logic;
      ***_proc_rh_wl   : in  std_logic;
      ***_proc_exec    : in  std_logic;
      ***_proc_op_done : out std_logic;
      ***_proc_address : in  std_logic_vector(13 downto 0);
      ***_proc_wr_data : in  std_logic_vector(31 downto 0);
      ***_proc_rd_data : out std_logic_vector(31 downto 0);

      xxx12345_&&&_rh_wl   : in  std_logic;
      xxx12345_&&&_exec    : in  std_logic;
      xxx12345_&&&_op_done : out std_logic;
      xxx12345_&&&_address : in  std_logic_vector(8 downto 0);
      xxx12345_&&&_wr_data : in  std_logic_vector(31 downto 0);
      xxx12345_&&&_rd_data : out std_logic_vector(31 downto 0);

      clkunknow_reset_l : in std_logic_vector(channel_number-1 downto 0);
      clkunknow         : in std_logic_vector(channel_number-1 downto 0);

      clkunknow_rxohfp : in std_logic_vector(channel_number-1 downto 0);
      clkunknow_rxohd  : in std_logic_vector(channel_number-1 downto 0);

      clkunknow_txohfp : in  std_logic_vector(channel_number-1 downto 0);
      clkunknow_txohd  : out std_logic_vector(channel_number-1 downto 0);

      ###_inclk : out std_logic;
      ###_ind0  : in  std_logic := '0';
      ###_ind1  : in  std_logic := '0';
      ###_ind2  : in  std_logic := '0';
      ###_ind3  : in  std_logic := '0';
      ###_indv  : in  std_logic := '0';

      ###_outclk : out std_logic;
      ###_outd0  : out std_logic;
      ###_outd1  : out std_logic;
      ###_outd2  : out std_logic;
      ###_outd3  : out std_logic;
      ###_outdv  : out std_logic;

      ?????_rx_d     : in std_logic_vector(7 downto 0) := (others => '0');
      ?????_rx_dv    : in std_logic                    := '0';
      ?????_rx_er    : in std_logic                    := '0';
      ?????_rxclk_en : in std_logic                    := '0';

      ?????_tx_d     : out std_logic_vector(7 downto 0);
      ?????_tx_en    : out std_logic;
      ?????_tx_er    : out std_logic;
      ?????_txclk_en : out std_logic
      );
end component;


component prbs31_8bit                                                               
  generic (                                                                    
    chk_mode     : boolean;                                                    
    data_out_reg : integer);                                                   
  port (                                                                       
    reset_l     : in  std_logic;                                               
    clk         : in  std_logic;                                               
    inv_pattern : in  std_logic;                                               
    data_in     : in  std_logic_vector(8 - 1 downto 0);                       
    en_in       : in  std_logic;                                               
    data_out    : out std_logic_vector(8 - 1 downto 0);                       
    en_out      : out std_logic);                                              
end component;      

component crc_gen
  port (
    rst         : in    std_logic;
    tx_clk            : in    std_logic;
    tx_clken        : in    std_logic;
    tx_d                : in    std_logic_vector(7 downto 0);
    tx_den            : in    std_logic;
    crc_out            : out    std_logic_vector(31 downto 0));
end component;

component crc_chk
  port (
    rst                    : in    std_logic;
    rx_clk            : in    std_logic;
    rx_clken        : in    std_logic;
    rx_d                : in    std_logic_vector(7 downto 0);
    rx_dv                : in    std_logic;
    rx_eop            : in    std_logic;
    crc_err            : out    std_logic);
end component;


signal reset_l                : std_logic;
signal clkUnknow                : std_logic;
signal clkunknow                 : std_logic_vector(channel_number-1 downto 0);
signal clkunknow_reset_l         : std_logic_vector(channel_number-1 downto 0);
signal ***_rh_wl                  : std_logic;
signal ***_exec                   : std_logic;
signal ***_op_done                : std_logic;
signal ***_address                : std_logic_vector(13 downto 0);
signal ***_wr_data                : std_logic_vector(31 downto 0);
signal ***_rd_data                : std_logic_vector(31 downto 0);
signal &&&&_rh_wl                  : std_logic;
signal &&&&_exec                   : std_logic;
signal &&&&_op_done                : std_logic;
signal &&&&_address                : std_logic_vector(8 downto 0);
signal &&&&_wr_data                : std_logic_vector(31 downto 0);
signal &&&&_rd_data                : std_logic_vector(31 downto 0);


signal clkunknow_rxohfp : std_logic_vector(channel_number-1 downto 0);
signal clkunknow_rxohd  : std_logic_vector(channel_number-1 downto 0);

signal clkunknow_txohfp : std_logic_vector(channel_number-1 downto 0);
signal clkunknow_txohd  : std_logic_vector(channel_number-1 downto 0);


signal ?????_rx_d             : std_logic_vector(7 downto 0);
signal ?????_rx_dv                        : std_logic;
signal ?????_rx_er                        : std_logic;
signal ?????_rxclk_en                    : std_logic;
signal ?????_tx_d                            : std_logic_vector(7 downto 0);
signal ?????_tx_en                        : std_logic;
signal ?????_tx_er                        : std_logic;
signal ?????_txclk_en                    : std_logic;

signal ?????_rx_crc_out : std_logic_vector(31 downto 0);
signal ?????_tx_eop            : std_logic;
signal ?????_tx_crc_err : std_logic;



signal prbs_gen_en_s : std_logic;
signal prbs_gen_en   : std_logic_vector(channel_number-1 downto 0);
signal prbs_gen_dout : STD_BUS_W8(channel_number-1 downto 0);

signal prbs_gen_dout_sel : std_logic_vector(7 downto 0);
signal prbs_chk_din_sel : std_logic_vector(7 downto 0);
signal prbs_chk_res_sel : std_logic_vector(7 downto 0);

signal prbs_chk_din  : STD_BUS_W8(channel_number-1 downto 0);
signal prbs_chk_dv   : std_logic_vector(channel_number-1 downto 0);
signal prbs_chk_dv_s : std_logic;
signal prbs_chk_res  : STD_BUS_W8(channel_number-1 downto 0);


signal prbs_gen_sel : std_logic_vector(7 downto 0) := X"01";
signal prbs_chk_sel : std_logic_vector(7 downto 0) := X"01";



signal reg_acc_no : integer := 0;
signal strobe_pkt_no    : integer := 0;
signal send_pkt_no        : integer := 0;

signal    ?????_rx_dv_crc : std_logic;
signal    ?????_tx_en_crc : std_logic;

signal    ?????_rxclk_en_crc : std_logic;

signal bitcount                     : std_logic_vector(9 downto 0);
signal bitcount_d2             : std_logic_vector(9 downto 0);
signal bytecount         : std_logic_vector(5 downto 0);
signal multiframecount   : std_logic_vector(7 downto 0);



constant ETHERNET_MIN_GAP : natural := 12;
constant PAYLOAD_LEN : natural := 64;  -- include DA--SA--VLAN tag--TYPE--Physical Channel ID--ECC ID--CRC--total 27,1573 contents
constant PACKET_NUMBER : natural := 5;  -- packet number you wanna send on each channel


type port_map_list_type is array (natural range<>) of natural;
constant ?????_tx_port_map_list : port_map_list_type := (1,2,3,4,5,6,7,8,9,10,11,12);  
constant ?????_rx_port_map_list : port_map_list_type := (1,2,3,4,5,6,7,8,9,10,11,12);


signal reg_config_done : std_logic;     -- reg configuration complete flag singal



begin 
 
    process
        begin
             reset_l <= '0';
             wait for 100 ns;
             reset_l <= '1';
             wait;
        end process;

    process
        begin
             clkunknow_reset_l <= (others => '0');
             wait for 100 ns;
             clkunknow_reset_l <= (others => '1');
             wait;
        end process;
                 
        process
        begin
            clkUnknow <= '0';
            wait for 4 ns;
            clkUnknow <= '1';
            wait for 4 ns;
        end process;
         
        process
        begin
            clkunknow <= (others => '0');
            wait for 11.11 ns;
            clkunknow <= (others => '1');
            wait for 11.11 ns;
        end process;


    
    --selector of prbs_gen_en signal
    process(prbs_gen_sel,prbs_gen_en,prbs_gen_en_s,?????_rxclk_en)
      begin
        case prbs_gen_sel is
          when X"01" => prbs_gen_en(0) <= prbs_gen_en_s and ?????_rxclk_en;
          when X"02" => prbs_gen_en(1) <= prbs_gen_en_s and ?????_rxclk_en;
          when X"03" => prbs_gen_en(2) <= prbs_gen_en_s and ?????_rxclk_en;
          when X"04" => prbs_gen_en(3) <= prbs_gen_en_s and ?????_rxclk_en;
          when X"05" => prbs_gen_en(4) <= prbs_gen_en_s and ?????_rxclk_en;
          when X"06" => prbs_gen_en(5) <= prbs_gen_en_s and ?????_rxclk_en;
          when X"07" => prbs_gen_en(6) <= prbs_gen_en_s and ?????_rxclk_en;
          when X"08" => prbs_gen_en(7) <= prbs_gen_en_s and ?????_rxclk_en;
          when X"09" => prbs_gen_en(8) <= prbs_gen_en_s and ?????_rxclk_en;
          when X"0a" => prbs_gen_en(9) <= prbs_gen_en_s and ?????_rxclk_en;
          when X"0b" => prbs_gen_en(10) <= prbs_gen_en_s and ?????_rxclk_en;
          when X"0c" => prbs_gen_en(11) <= prbs_gen_en_s and ?????_rxclk_en;              
          when others => null;
        end case;
      end process;

    --selector of prbs_gen_dout_sel signal
    process(prbs_gen_sel,prbs_gen_dout_sel,prbs_gen_dout)
      begin
        case prbs_gen_sel is
          when X"01" => prbs_gen_dout_sel <= prbs_gen_dout(0);
          when X"02" => prbs_gen_dout_sel <= prbs_gen_dout(1);
          when X"03" => prbs_gen_dout_sel <= prbs_gen_dout(2);
          when X"04" => prbs_gen_dout_sel <= prbs_gen_dout(3);
          when X"05" => prbs_gen_dout_sel <= prbs_gen_dout(4);
          when X"06" => prbs_gen_dout_sel <= prbs_gen_dout(5);
          when X"07" => prbs_gen_dout_sel <= prbs_gen_dout(6);
          when X"08" => prbs_gen_dout_sel <= prbs_gen_dout(7);
          when X"09" => prbs_gen_dout_sel <= prbs_gen_dout(8);
          when X"0a" => prbs_gen_dout_sel <= prbs_gen_dout(9);
          when X"0b" => prbs_gen_dout_sel <= prbs_gen_dout(10);
          when X"0c" => prbs_gen_dout_sel <= prbs_gen_dout(11);              
          when others => null;
        end case;
      end process;


     --selector of prbs_chk_res_sel signal
     process(prbs_chk_sel,prbs_chk_res_sel,prbs_chk_res)
       begin
        case prbs_chk_sel is
          when X"01" => prbs_chk_res_sel <= prbs_chk_res(0);
          when X"02" => prbs_chk_res_sel <= prbs_chk_res(1);
          when X"03" => prbs_chk_res_sel <= prbs_chk_res(2);
          when X"04" => prbs_chk_res_sel <= prbs_chk_res(3);
          when X"05" => prbs_chk_res_sel <= prbs_chk_res(4);
          when X"06" => prbs_chk_res_sel <= prbs_chk_res(5);
          when X"07" => prbs_chk_res_sel <= prbs_chk_res(6);
          when X"08" => prbs_chk_res_sel <= prbs_chk_res(7);
          when X"09" => prbs_chk_res_sel <= prbs_chk_res(8);
          when X"0a" => prbs_chk_res_sel <= prbs_chk_res(9);
          when X"0b" => prbs_chk_res_sel <= prbs_chk_res(10);
          when X"0c" => prbs_chk_res_sel <= prbs_chk_res(11);              
          when others => null;
        end case;
       end process;


     --selector of prbs_chk_din signal
     process(prbs_chk_sel,prbs_chk_din,prbs_chk_din_sel)
       begin
        case prbs_chk_sel is
          when X"01" => prbs_chk_din(0)  <= prbs_chk_din_sel;
          when X"02" => prbs_chk_din(1)  <= prbs_chk_din_sel;
          when X"03" => prbs_chk_din(2)  <= prbs_chk_din_sel;
          when X"04" => prbs_chk_din(3)  <= prbs_chk_din_sel;
          when X"05" => prbs_chk_din(4)  <= prbs_chk_din_sel;
          when X"06" => prbs_chk_din(5)  <= prbs_chk_din_sel;
          when X"07" => prbs_chk_din(6)  <= prbs_chk_din_sel;
          when X"08" => prbs_chk_din(7)  <= prbs_chk_din_sel;
          when X"09" => prbs_chk_din(8)  <= prbs_chk_din_sel;
          when X"0a" => prbs_chk_din(9)  <= prbs_chk_din_sel;
          when X"0b" => prbs_chk_din(10)  <= prbs_chk_din_sel;
          when X"0c" => prbs_chk_din(11)  <= prbs_chk_din_sel;              
          when others => null;
        end case;
       end process;

     --selector of prbs_chk_dv  signal
     process(prbs_chk_sel,prbs_chk_dv,prbs_chk_dv_s,?????_txclk_en)
       begin
        case prbs_chk_sel is
          when X"01" => prbs_chk_dv(0)  <= prbs_chk_dv_s and ?????_txclk_en;
          when X"02" => prbs_chk_dv(1)  <= prbs_chk_dv_s and ?????_txclk_en;
          when X"03" => prbs_chk_dv(2)  <= prbs_chk_dv_s and ?????_txclk_en;
          when X"04" => prbs_chk_dv(3)  <= prbs_chk_dv_s and ?????_txclk_en;
          when X"05" => prbs_chk_dv(4)  <= prbs_chk_dv_s and ?????_txclk_en;
          when X"06" => prbs_chk_dv(5)  <= prbs_chk_dv_s and ?????_txclk_en;
          when X"07" => prbs_chk_dv(6)  <= prbs_chk_dv_s and ?????_txclk_en;
          when X"08" => prbs_chk_dv(7)  <= prbs_chk_dv_s and ?????_txclk_en;
          when X"09" => prbs_chk_dv(8)  <= prbs_chk_dv_s and ?????_txclk_en;
          when X"0a" => prbs_chk_dv(9)  <= prbs_chk_dv_s and ?????_txclk_en;
          when X"0b" => prbs_chk_dv(10)  <= prbs_chk_dv_s and ?????_txclk_en;
          when X"0c" => prbs_chk_dv(11)  <= prbs_chk_dv_s and ?????_txclk_en;              
          when others => null;
        end case;
       end process;   

       
         
    ----------------------------------------------------------------------------------------------------------------------
    ---- packet send Configuration
    ----------------------------------------------------------------------------------------------------------------------
    crc_gen_1: crc_gen
            port map (
                rst                        => reset_l,
                tx_clk                => clkUnknow,
                tx_clken            => ?????_rxclk_en_crc,
                tx_d                    => ?????_rx_d,
                tx_den                => ?????_rx_dv_crc,
                crc_out                => ?????_rx_crc_out);
         
        crc_chk_1: crc_chk
            port map (
                rst                        => reset_l,
                rx_clk                => clkUnknow,
                rx_clken            => ?????_txclk_en,
                rx_d                    => ?????_tx_d,
                rx_dv                    => ?????_tx_en_crc,
                rx_eop                => ?????_tx_eop,
                crc_err                => ?????_tx_crc_err);
         
         

    
    --generate individual prbs blocks for each channel
    prbs_gen: for i in 0 to channel_number-1 generate
      prbs31_8bit_gen:prbs31_8bit
        generic map (
          chk_mode     => false,
          data_out_reg => 0)
        port map (
          reset_l            => reset_l,
          clk                    => clkUnknow,
          inv_pattern => '0',
          data_in            => (others=>'0'),
          en_in                => prbs_gen_en(i),
          data_out        => prbs_gen_dout(i),
          en_out            => open);

      
        prbs31_8bit_chk: prbs31_8bit
            generic map (
                chk_mode         => true,
                data_out_reg => 0)
            port map (
                reset_l            => reset_l,
                clk                    => clkUnknow,
                inv_pattern => '0',
                data_in            => prbs_chk_din(i),
                en_in                => prbs_chk_dv(i),
                data_out        => prbs_chk_res(i),
                en_out            => open);
   
    end generate prbs_gen;

     
         
    process
        begin
            for i in 0 to 9 loop
                wait until rising_edge(clkUnknow);
                if i=6 then     ?????_rxclk_en_crc<='1'; else    ?????_rxclk_en_crc <='0';         end if;
                if i=8 then     ?????_rxclk_en<='1'; else    ?????_rxclk_en <='0';         end if;
            end loop;     -- i in rang 0 to 9 loop
        end process;
         
        ?????_rx_er <= '0';
         
--modified by ys
    process (clkunknow(0), clkunknow_reset_l(0))
        begin
            if (clkunknow_reset_l(0) = '0') then
                bitcount <= (others => '0');
        bitcount_d2 <= (others => '0');      
            elsif (clkunknow(0)'event and clkunknow(0) = '1') then
        bitcount <= bitcount + 1;
        if bitcount = "0000000010" then 
          bitcount_d2 <= (others => '0');       
        else
          bitcount_d2 <= bitcount_d2 + 1;
        end if;        
            end if;
        end process;

        bytecount <= bitcount_d2(8 downto 3);
         
        process (clkunknow(0), clkunknow_reset_l(0))
        begin
            if (clkunknow_reset_l(0) = '0') then
                clkunknow_txohfp <= (others => '0');
       
        multiframecount <= (others => '0');
            elsif (clkunknow(0)'event and clkunknow(0) = '1') then       
        if bitcount = "0000000001" then         
          clkunknow_txohfp <= (others => '1');
        elsif bitcount = "0000000010" and multiframecount = "11111111" then 
           clkunknow_txohfp <= (others => '1');
        elsif bitcount = "1111111111" then
          multiframecount <= multiframecount + 1;
          clkunknow_txohfp <= (others => '0');
        else
          clkunknow_txohfp <= (others => '0');
        end if;        
            end if;
        end process;
--end of modification

         

       
        xxx12345_&&&_1: xxx12345_&&&
            generic map (
                ###_enable                     =>0,
                channel_number             =>12,
                max_channel_id             =>20,
                ethernet_head_length =>23
                )
            port map (
                clkUnknow_reset_l     => reset_l, 
                clkUnknow                     => clkUnknow,                 
                ***_proc_rh_wl     => ***_rh_wl,    
                ***_proc_exec         => ***_exec,        
                ***_proc_op_done => ***_op_done,
                ***_proc_address => ***_address,
                ***_proc_wr_data => ***_wr_data,
                ***_proc_rd_data => ***_rd_data,
                 
                xxx12345_&&&_rh_wl        => &&&&_rh_wl,    
                xxx12345_&&&_exec        => &&&&_exec,         
                xxx12345_&&&_op_done => &&&&_op_done, 
                xxx12345_&&&_address => &&&&_address, 
                xxx12345_&&&_wr_data => &&&&_wr_data, 
                xxx12345_&&&_rd_data => &&&&_rd_data, 
                 
                clkunknow_reset_l => clkunknow_reset_l,
                clkunknow                 => clkunknow,                                
                clkunknow_rxohfp     => clkunknow_rxohfp, 
                clkunknow_rxohd     => clkunknow_rxohd,             
                clkunknow_txohfp     => clkunknow_txohfp, 
                clkunknow_txohd     => clkunknow_txohd,     
                 
                ###_inclk => open, 
                ###_ind0    => open,    
                ###_ind1    => open,    
                ###_ind2    => open,    
                ###_ind3    => open,    
                ###_indv    => open,    
                 
                ###_outclk => open,
                ###_outd0     => open, 
                ###_outd1     => open, 
                ###_outd2     => open, 
                ###_outd3     => open, 
                ###_outdv     => open, 
                 
                ?????_rx_d         => ?????_rx_d,            
                ?????_rx_dv         => ?????_rx_dv,     
                ?????_rx_er         => ?????_rx_er,     
                ?????_rxclk_en => ?????_rxclk_en,
                 
                ?????_tx_d         => ?????_tx_d,         
                ?????_tx_en         => ?????_tx_en,     
                ?????_tx_er         => ?????_tx_er,     
                ?????_txclk_en => ?????_txclk_en
                );
         
         
         clkunknow_rxohfp <= clkunknow_txohfp;
         clkunknow_rxohd  <= clkunknow_txohd;
         
    Packet_Send : process
         
                variable bit_rate : integer range 0 to 5000000 := 5000000;
                variable pkt_len : integer range 0 to 1700 := 1600;
                variable crc_value : std_logic_vector(31 downto 0);
        variable time_record : time;    -- use to record packet send process time
        variable bit_rate_map_gap : real;
        
                procedure regular_pkt_send (
                    DA        : in std_logic_vector(47 downto 0);
                    SA        : in std_logic_vector(47 downto 0);
                    VLAN_TAG : in std_logic_vector(31 downto 0);
                    ETH_TYPE : in std_logic_vector(15 downto 0);
                    PHY_CHAN : in std_logic_vector(23 downto 0);
                    ECC_ID     : in std_logic_vector(15 downto 0);
                    PAYLOAD     : in std_logic_vector(7 downto 0);
                    PAYLOAD_LEN : in integer range 0 to 1600;
                    CRC_MASK : in std_logic_vector(31 downto 0)) is
                begin
         
                    printf("*send_packet #%x--",send_pkt_no); send_pkt_no <= send_pkt_no+1;
                    printf("DA : %012x SA: %012x VLAN_TAG: %08x ETH_TYPE: %04x PHY_CHAN: %06x ECC_ID: %04x\n",DA,SA,VLAN_TAG,ETH_TYPE,PHY_CHAN,ECC_ID);


          prbs_gen_sel <= PHY_CHAN(23 downto 16);


          
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         ?????_rx_d <= X"55";     ?????_rx_dv <= '1';
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         ?????_rx_d <= X"55";
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         ?????_rx_d <= X"55";
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         ?????_rx_d <= X"55";
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         ?????_rx_d <= X"55";
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         ?????_rx_d <= X"55";
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         ?????_rx_d <= X"55";
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         ?????_rx_d <= X"d5";
            
         
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         ?????_rx_d <= DA(47 downto 40); ?????_rx_dv_crc <= '1';
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         ?????_rx_d <= DA(39 downto 32); 
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         ?????_rx_d <= DA(31 downto 24);                    
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         ?????_rx_d <= DA(23 downto 16); 
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         ?????_rx_d <= DA(15 downto 8);     
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         ?????_rx_d <= DA(7     downto 0);     
                    
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         ?????_rx_d <= SA(47 downto 40); 
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         ?????_rx_d <= SA(39 downto 32); 
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         ?????_rx_d <= SA(31 downto 24);                    
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         ?????_rx_d <= SA(23 downto 16); 
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         ?????_rx_d <= SA(15 downto 8);     
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         ?????_rx_d <= SA(7     downto 0);     
         
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         ?????_rx_d <= VLAN_TAG(31 downto 24);                    
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         ?????_rx_d <= VLAN_TAG(23 downto 16); 
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         ?????_rx_d <= VLAN_TAG(15 downto 8);     
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         ?????_rx_d <= VLAN_TAG(7     downto 0);
         
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         ?????_rx_d <= ETH_TYPE(15 downto 8);     
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         ?????_rx_d <= ETH_TYPE(7     downto 0);     
                    
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         ?????_rx_d <= PHY_CHAN(23 downto 16); 
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         ?????_rx_d <= PHY_CHAN(15 downto 8);     
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         ?????_rx_d <= PHY_CHAN(7     downto 0);
         
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         ?????_rx_d <= ECC_ID(15 downto 8);     --prbs_gen_en_s <= '1'; 
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         ?????_rx_d <= ECC_ID(7     downto 0); 


          
          wait until rising_clken(clkUnknow,?????_rxclk_en);     ?????_rx_d <= conv_std_logic_vector(PAYLOAD_LEN,16)(15 downto 8);

          wait until rising_clken(clkUnknow,?????_rxclk_en);     ?????_rx_d <= conv_std_logic_vector(PAYLOAD_LEN,16)(7 downto 0);
          
          wait until rising_clken(clkUnknow,?????_rxclk_en);     ?????_rx_d <= conv_std_logic_vector(send_pkt_no,16)(15 downto 8);
                                                               prbs_gen_en_s <= '1';  -- enable prbs submodule,
                                                                                      -- enable signal need 2clk ahead
                                                                                      -- before payload
          wait until rising_clken(clkUnknow,?????_rxclk_en);     ?????_rx_d <= conv_std_logic_vector(send_pkt_no,16)(7 downto 0);     


          
                    for i in 0 to PAYLOAD_LEN-1-4 loop  -- include 4 bytes added(payload_len*2,packet_num*2)
                        if i=PAYLOAD_LEN-1-4 then
                            prbs_gen_en_s <= '0';
                        end if;
                        wait until rising_clken(clkUnknow,?????_rxclk_en);        ?????_rx_d <= prbs_gen_dout_sel; --?????_rx_d <= x"55";
                    end loop;     -- i in rang 0 to 8 loop
         
                 
                    
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         
                    crc_value     := ?????_rx_crc_out XOR CRC_MASK;
                    ?????_rx_d <= crc_value(31 downto 24);                    
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         ?????_rx_d <= crc_value(23 downto 16); 
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         ?????_rx_d <= crc_value(15 downto 8);     
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         ?????_rx_d <= crc_value(7 downto 0);                     
         
                    wait until rising_clken(clkUnknow,?????_rxclk_en);         ?????_rx_d <= x"00";     ?????_rx_dv <= '0'; ?????_rx_dv_crc<='0';


          
          for i in 0 to ETHERNET_MIN_GAP-1 loop
            wait until rising_clken(clkUnknow,?????_rxclk_en);
          end loop;  -- i
          

         
                end regular_pkt_send;
         
        begin
                ?????_rx_d     <= x"00";     
                ?????_rx_dv     <= '0';
                ?????_rx_dv_crc <= '0';
                prbs_gen_en_s<= '0';
                
                
                --wait for 10 us;

        bit_rate :=5000000;        --5MHz                                                                                --logic_1
        
        wait until reg_config_done = '1';  -- pkt send begin after configuration process finished

        
        for k in 1 to PACKET_NUMBER loop
          time_record := now;
          for i in 1 to channel_number loop
            regular_pkt_send(X"DD1122334455",X"111111222222",X"81008200",X"88b7",conv_std_logic_vector(?????_rx_port_map_list(i-1),8)&x"02"&conv_std_logic_vector(?????_rx_port_map_list(i-1),8),X"0000",X"D5",PAYLOAD_LEN,X"00000000");
          end loop;   --i channel loop

          time_record := now - time_record;
          bit_rate_map_gap := real(payload_len*10e4)/((255.0/237.0 * 99532.8)*(2.0/(4080.0*4.0)));
          printf("%f\n",bit_rate_map_gap);
          wait for bit_rate_map_gap*1 ns - time_record;  -- wait enough time to meet ODU bit rate
        end loop;   --k : packet number loop
            
                wait;
             
        end process Packet_Send;
         
         
         
        Packet_Receive : process
         
                variable oh_match :std_logic;
                variable prbs_match :std_logic;
                variable crc_match :std_logic;
                variable is_match :std_logic;

        variable seq_num : std_logic_vector(15 downto 0);
        
                
                procedure regular_pkt_receive (
                    DA        : in std_logic_vector(47 downto 0);
                    SA        : in std_logic_vector(47 downto 0);
                    VLAN_TAG : in std_logic_vector(31 downto 0);
                    ETH_TYPE : in std_logic_vector(15 downto 0);
                    PHY_CHAN : in std_logic_vector(23 downto 0);
                    ECC_ID     : in std_logic_vector(15 downto 0);
                    PAYLOAD     : in std_logic_vector(7 downto 0);
                    PAYLOAD_LEN : in integer range 0 to 1600;
                    CRC_MASK : in std_logic_vector(31 downto 0)) is
                begin
         
                    oh_match := '1';
                    prbs_match := '1';
                    crc_match := '1';
                    is_match := '1';
         
                    wait until (rising_clken(clkUnknow,?????_txclk_en) and ?????_tx_en='1');
                    printf("*strobe packet #%x: ",strobe_pkt_no); strobe_pkt_no <= strobe_pkt_no+1;
                    printf("DA : %012x SA: %012x VLAN_TAG: %08x ETH_TYPE: %04x PHY_CHAN: %06x ECC_ID: %04x\n",DA,SA,VLAN_TAG,ETH_TYPE,PHY_CHAN,ECC_ID);
                    wait until rising_clken(clkUnknow,?????_txclk_en);
                    wait until rising_clken(clkUnknow,?????_txclk_en);
                    wait until rising_clken(clkUnknow,?????_txclk_en);
                    wait until rising_clken(clkUnknow,?????_txclk_en);
                    wait until rising_clken(clkUnknow,?????_txclk_en);
                    wait until rising_clken(clkUnknow,?????_txclk_en);
                    wait until rising_clken(clkUnknow,?????_txclk_en);        ?????_tx_en_crc <= '1';
         
                    wait until rising_clken(clkUnknow,?????_txclk_en);        if DA(47 downto 40) /= ?????_tx_d then oh_match :='0'; end if;
                    wait until rising_clken(clkUnknow,?????_txclk_en);        if DA(39 downto 32)    /= ?????_tx_d then oh_match :='0'; end if;
                    wait until rising_clken(clkUnknow,?????_txclk_en);        if DA(31 downto 24)    /= ?????_tx_d then oh_match :='0'; end if;
                    wait until rising_clken(clkUnknow,?????_txclk_en);        if DA(23 downto 16)    /= ?????_tx_d then oh_match :='0'; end if;
                    wait until rising_clken(clkUnknow,?????_txclk_en);        if DA(15 downto 8)    /= ?????_tx_d then oh_match :='0'; end if;
                    wait until rising_clken(clkUnknow,?????_txclk_en);        if DA(7     downto 0)    /= ?????_tx_d then oh_match :='0'; end if;
                                                                                                                                                                                                         
                    wait until rising_clken(clkUnknow,?????_txclk_en);        if SA(47 downto 40)    /= ?????_tx_d then oh_match :='0'; end if;
                    wait until rising_clken(clkUnknow,?????_txclk_en);        if SA(39 downto 32)    /= ?????_tx_d then oh_match :='0'; end if;
                    wait until rising_clken(clkUnknow,?????_txclk_en);        if SA(31 downto 24)    /= ?????_tx_d then oh_match :='0'; end if;
                    wait until rising_clken(clkUnknow,?????_txclk_en);        if SA(23 downto 16)    /= ?????_tx_d then oh_match :='0'; end if;
                    wait until rising_clken(clkUnknow,?????_txclk_en);        if SA(15 downto 8)    /= ?????_tx_d then oh_match :='0'; end if;
                    wait until rising_clken(clkUnknow,?????_txclk_en);        if SA(7     downto 0)    /= ?????_tx_d then oh_match :='0'; end if;
         
                    wait until rising_clken(clkUnknow,?????_txclk_en);        if VLAN_TAG(31 downto 24)    /= ?????_tx_d then oh_match :='0'; end if;
                    wait until rising_clken(clkUnknow,?????_txclk_en);        if VLAN_TAG(23 downto 16)    /= ?????_tx_d then oh_match :='0'; end if;
                    wait until rising_clken(clkUnknow,?????_txclk_en);        if VLAN_TAG(15 downto 8)    /= ?????_tx_d then oh_match :='0'; end if;
                    wait until rising_clken(clkUnknow,?????_txclk_en);        if VLAN_TAG(7     downto 0)    /= ?????_tx_d then oh_match :='0'; end if;
                                                                                                                                                                                                                     
                    wait until rising_clken(clkUnknow,?????_txclk_en);        if ETH_TYPE(15 downto 8)    /= ?????_tx_d then oh_match :='0'; end if;
                    wait until rising_clken(clkUnknow,?????_txclk_en);        if ETH_TYPE(7    downto 0)        /= ?????_tx_d then oh_match :='0'; end if;

          -- ignore phy_chan in oh match check process for receiving packets will arrive in random order
                    wait until rising_clken(clkUnknow,?????_txclk_en);        --if PHY_CHAN(23 downto 16)    /= ?????_tx_d then oh_match :='1'; end if;

          --modified by ys
          prbs_chk_sel <= ?????_tx_d;
          --end of modification

                    wait until rising_clken(clkUnknow,?????_txclk_en);        if PHY_CHAN(15 downto 8)    /= ?????_tx_d then oh_match :='1'; end if;
                    wait until rising_clken(clkUnknow,?????_txclk_en);        --if PHY_CHAN(7    downto 0)        /= ?????_tx_d then oh_match :='1'; end if;

          
                    wait until rising_clken(clkUnknow,?????_txclk_en);        if ECC_ID(15 downto 8)        /= ?????_tx_d then oh_match :='0'; end if;
                                                                                                                                                                                                                     
                    wait until rising_clken(clkUnknow,?????_txclk_en);        if ECC_ID(7     downto 0)        /= ?????_tx_d then oh_match :='0'; end if;

          wait until rising_clken(clkUnknow,?????_txclk_en);   -- PAYLOAD_LEN(15 downto 8) := ?????_tx_d; -- in this
                                                             -- version the receive payload length is set by the module
                                                             -- input, will change in other version
          wait until rising_clken(clkUnknow,?????_txclk_en);    --PAYLOAD_LEN(7 downto 0)  := ?????_tx_d;
          wait until rising_clken(clkUnknow,?????_txclk_en);    seq_num(15 downto 8) := ?????_tx_d;
          wait until rising_clken(clkUnknow,?????_txclk_en);    seq_num(7 downto 0)  := ?????_tx_d;


          
                    if oh_match='0' then 
                        printf("-- oh mismatch!\n");
                    end if;

          --modified by ys, reduce 4 clk for payload_len bytes and seq_num bytes
                    for i in 0 to PAYLOAD_LEN-1-4 loop  -- modify --add 4 bytes
         
                        wait until rising_clken(clkUnknow,?????_txclk_en);     prbs_chk_din_sel <=    ?????_tx_d;
                        if i=0 then     wait until rising_edge(clkUnknow);prbs_chk_dv_s <= '1';     end if;                                            
                        if i/=0 and prbs_chk_res_sel /= "00000000" then prbs_match:='0';
            printf("-- prbs_chk_res_sel: 0x%02x\n",prbs_chk_res_sel); end if;
                    end loop;     -- i in rang 0 to PAYLOAD_LEN loop
         
                    if prbs_match='0' then 
                        printf("-- prbs mismatch!\n");
                    end if; 
                    
                    for i in 0 to 3 loop
                        wait until rising_clken(clkUnknow,?????_txclk_en);     prbs_chk_din_sel <=    ?????_tx_d;
                        if i=0 then prbs_chk_dv_s <= '0'; end if;
                    end loop;     -- i in rang 0 to 3 loop
         
                    ?????_tx_eop <= '1';
                    wait until rising_clken(clkUnknow,?????_txclk_en);
                    ?????_tx_eop <= '0';
                    ?????_tx_en_crc     <= '0';
                    
                    if ?????_tx_crc_err = '1' then crc_match :='0'; end if;
                    if crc_match='0' then 
                        printf("-- crc error!\n");
                    end if;
         
                    if oh_match='0' or prbs_match='0' or crc_match='0' then
                        is_match := '0';
                        printf("-- error! receive mismatch!\n");
                    else
                        printf("-- ok! receive match!\n");
                    end if;
                
                end regular_pkt_receive;
         
        begin
                ?????_tx_eop    <= '0';
                ?????_tx_en_crc <= '0';
                prbs_chk_din_sel    <= (others=>'0');
                prbs_chk_dv_s <= '0';
                    
                wait for 800 ns;

      
        for k in 1 to PACKET_NUMBER loop
          for i in 1 to channel_number loop
            regular_pkt_receive(X"112233445566",X"aaaaaa555555",X"81008200",X"88b7",conv_std_logic_vector(?????_rx_port_map_list(i-1),8)&x"02"&conv_std_logic_vector(?????_rx_port_map_list(i-1),8),X"0000",X"D5",PAYLOAD_LEN,X"00000000");
          end loop;   --i
        end loop;   --k

        
                wait;

         
        end process Packet_Receive;
         
         
    --------------------------------------------------------------------------------------------------------------------
        -- HOST initial Configuration
        --------------------------------------------------------------------------------------------------------------------
        Host_Conf : process
                variable ***_read_value : std_logic_vector(31 downto 0);
                variable &&&&_read_value : std_logic_vector(31 downto 0);

        variable ***_chan_enable : bit_vector(31 downto 0);
                
                procedure ***_reg_write (
                    ***_addr    : in std_logic_vector(31 downto 0);
                    ***_value : in std_logic_vector(31 downto 0)) is
                begin
                    printf("***_reg_write 0x%08x 0x%08x\n",***_addr,***_value);
                    wait until rising_edge(clkUnknow);
                    ***_exec         <= '0';
                    ***_address     <= ***_addr(13 downto 0);
                    ***_wr_data     <= ***_value;
                    wait until rising_edge(clkUnknow);
                    ***_exec         <= '1';
                    ***_rh_wl         <= '0';
                    wait until rising_edge(clkUnknow);
                    ***_exec         <= '0';
                    wait until ***_op_done = '1';
                    ***_rh_wl         <= '1';
                    wait until rising_edge(clkUnknow);
                end ***_reg_write;
                 
                procedure ***_reg_read (
                    ***_addr                     : in     std_logic_vector(31 downto 0);
                    variable ***_value : out std_logic_vector(31 downto 0)) is
                begin
                    
                    wait until rising_edge(clkUnknow);
                    ***_exec         <= '0';
                    ***_address     <= ***_addr(13 downto 0);
                    wait until rising_edge(clkUnknow);
                    ***_exec         <= '1';
                    ***_rh_wl         <= '1';
                    wait until rising_edge(clkUnknow);
                    ***_exec         <= '0';
                    wait until rising_edge(clkUnknow) and ***_op_done = '1';
                    ***_value                 := ***_rd_data;
                    printf("***_reg_read 0x%08x 0x%08x\n",***_addr,***_rd_data);
                    wait until clkUnknow'event and clkUnknow = '1';
                    
                end ***_reg_read;
         
                procedure &&&&_reg_write (
                    &&&&_addr    : in std_logic_vector(31 downto 0);
                    &&&&_value : in std_logic_vector(31 downto 0)) is
                begin
                    printf("&&&&_reg_write 0x%08x 0x%08x\n",&&&&_addr,&&&&_value);
                    wait until rising_edge(clkUnknow);
                    &&&&_exec         <= '0';
                    &&&&_address    <= &&&&_addr(8 downto 0);
                    &&&&_wr_data    <= &&&&_value;
                    wait until rising_edge(clkUnknow);
                    &&&&_exec         <= '1';
                    &&&&_rh_wl        <= '0';
                    wait until rising_edge(clkUnknow);
                    &&&&_exec             <= '0';
                    wait until &&&&_op_done = '1';
                    &&&&_rh_wl     <= '1';
                    wait until rising_edge(clkUnknow);
                end &&&&_reg_write;
                 
                procedure &&&&_reg_read (
                    &&&&_addr                     : in     std_logic_vector(31 downto 0);
                    variable &&&&_value : out std_logic_vector(31 downto 0)) is
                begin
                    
                    wait until rising_edge(clkUnknow);
                    &&&&_exec         <= '0';
                    &&&&_address    <= &&&&_addr(8 downto 0);
                    wait until rising_edge(clkUnknow);
                    &&&&_exec         <= '1';
                    &&&&_rh_wl        <= '1';
                    wait until rising_edge(clkUnknow);
                    &&&&_exec         <= '0';
                    wait until rising_edge(clkUnknow) and &&&&_op_done = '1';
                    &&&&_value                 := &&&&_rd_data;
                    printf("&&&&_reg_read 0x%08x 0x%08x\n",&&&&_addr,&&&&_rd_data);
                    wait until clkUnknow'event and clkUnknow = '1';
                    
                end &&&&_reg_read;
                
                
        begin

        reg_config_done <= '0';         -- register configuration process signal: 0--not finish yet 1--finished
      

      
                ***_rh_wl <= '1';     
                ***_exec    <= '0';
                ***_address <= (others => '0');
                ***_wr_data <= (others => '0');
         
                &&&&_rh_wl <= '1';     
                &&&&_exec     <= '0';
                &&&&_address <= (others => '0');
                &&&&_wr_data <= (others => '0');
                wait for 1000 ns;
        ------------------------------------------------------------------------------------------------------------------------
        -- testcase register config
        ------------------------------------------------------------------------------------------------------------------------

        ***_reg_write(x"0000_0000",x"0000_ffff");     --FUNCTION_ENABLE_31_0  initial all channel
                ***_reg_write(x"0000_0001",x"0000_0000");     --FUNCTION_ENABLE_63_32


        --*** to mac
        for i in 1 to channel_number loop
          ***_reg_write(x"0000_1"&conv_std_logic_vector((i-1)*4,8)&x"0", x"1122_3344");  --da & sa
          ***_reg_write(x"0000_1"&conv_std_logic_vector((i-1)*4,8)&x"1", x"5566_aaaa");
          ***_reg_write(x"0000_1"&conv_std_logic_vector((i-1)*4,8)&x"2", x"aa55_5555");
          ***_reg_write(x"0000_1"&conv_std_logic_vector((i-1)*4,8)&x"3", x"8100_8200");  -- vlan
          ***_reg_write(x"0000_1"&conv_std_logic_vector((i-1)*4,8)&x"4", x"88b7"&conv_std_logic_vector(i,8)&x"02");  -- phy_chan_id
          ***_reg_write(x"0000_1"&conv_std_logic_vector((i-1)*4,8)&x"5", conv_std_logic_vector(i,8)&x"00_00d5");  -- ecc_id
        end loop;  -- i

        --mac to ***
        for i in 1 to channel_number loop
          ***_reg_write(x"0000_1"&conv_std_logic_vector((i-1)*4+1,8)&x"0", x"dd11_2233");  --da & sa
          ***_reg_write(x"0000_1"&conv_std_logic_vector((i-1)*4+1,8)&x"1", x"4455_1111");
          ***_reg_write(x"0000_1"&conv_std_logic_vector((i-1)*4+1,8)&x"2", x"1122_2222");
          ***_reg_write(x"0000_1"&conv_std_logic_vector((i-1)*4+1,8)&x"3", x"8100_8200");  -- vlan
          ***_reg_write(x"0000_1"&conv_std_logic_vector((i-1)*4+1,8)&x"4",x"88b7"&conv_std_logic_vector(i,8)&x"02");  -- phy_chan_id
          ***_reg_write(x"0000_1"&conv_std_logic_vector((i-1)*4+1,8)&x"5", conv_std_logic_vector(i,8)&x"00_00d5");  -- ecc_id
        end loop;  -- i
        


        
        for i in 0 to channel_number-1 loop
          &&&&_reg_write(x"0000_000"&conv_std_logic_vector(i,4),x"0000_0000");
          &&&&_reg_read(x"0000_000"&conv_std_logic_vector(i,4),&&&&_read_value);
        end loop;  -- i

        --reg config done, pkt send send start
        reg_config_done <= '1';

                wait;
        end process Host_Conf;
      
    
end sch;
View Code

 

 

  最近的目标是,在进一步了解UVM的功能特性之后,将UVM方法学移植到现有的测试平台上去,看是否能对现有的测试平台提供帮助,提升代码测试的效果。

 

 

 

 

 

 

 

 

  

  

*****

你可能感兴趣的:(一些uvm的学习体会)