一些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應用指南及源碼分析)

而簡單的驗證平台可能只包含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方法學移植到現有的測試平台上去,看是否能對現有的測試平台提供幫助,提升代碼測試的效果。

 

 

 

 

 

 

 

 

  

  

*****


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM