天天看點

關于我的UVM驗證的第一個程式

這是我寫的第一個測試

首先這個程式是TPO516的RX方向的一個component 我們管這個部分叫做FAS Regen. 它的作用就是給一個overhead被破壞掉的OTN frame重新插入正确的fas信号既f6f6f6282828,一共48bit.

這個程式一共有4部分組成,分别是:fas regen_env下的fasregen_checker和otu4_data_interface;在頂層中的otu_top_harness,以及top test case:FASRegenTest。

這個程式用了一個叫做two kingdom factory的trick 他的目的是利用OTU4DataInterface::type_id::set_type_override(FASRegenInterface::get_type());這句話來overide out4data_interface.即叫做custmize function。

第一步,借鑒别人的datainterface code:

/×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××

×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××

`ifndef OTU4DataInterface_sv

`define OTU4DataInterface_sv

class OTU4DataInterface extends uvm_component;

  `uvm_component_utils(OTU4DataInterface)

  function new(string name = "", uvm_component parent = null);

    super.new(name, parent);

  endfunction

  virtual task sync();

  endtask

  virtual task read(output bit [319:0] data, output bit enable);

  endtask 

endclass

`endif //OTU4DataInterface_sv

//可以看到在這個code中,sync()和 read()function都是空的 友善以後override。

××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××

××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××/

第二步 在圖—top— harness裡面寫入FasRegenInterface.這個程式是用來override datapathinterface的function。首先這個方程需要找到兩個來個ntc_otu_top_320的接口。一個為enable一個為inpute data。在top320中RX PATH,INSERT FAS BYTE中enable 信号為rx_lite_frm_oof_fas_en,data為fas regen data. 将這兩個信号賦給harness中的readfunction的 data和enable,這樣就完成了data的進入dut的這個過程。這個語句always @(posedge sys_clk) fas_regen_enable <= dut.rx_lite_frm_oof_fas_en;使fas—en比regen—enable早一拍。

/×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××

×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××

logic fas_regen_enable;

  always @(posedge sys_clk) fas_regen_enable <= dut.rx_lite_frm_oof_fas_en;

  class FASRegenInterface extends OTU4DataInterface;

    `uvm_component_utils(FASRegenInterface)

    function new(string name = "", uvm_component parent = null);

      super.new(name, parent);

    endfunction

    virtual task sync();

      @(posedge sys_clk);

    endtask

    virtual task read(output bit[319:0] data, output bit enable);

      data = dut.rx_fas_regen_data;

      enable = fas_regen_enable;

    endtask

  endclass 

××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××

***************************************************************************************************************************/

下一個module是fas policy。他的作用是把6個fas bytes打亂,然後進入dut。

  constraint solve_order        {solve bad_fas before mask;}

  constraint frame_size         {random_frames > 0; random_frames < 2000;}

  constraint fas_dist           {bad_fas dist {0:=good_fas_dist, 1:=bad_fas_dist};}//指定bad fas為1。good為2  weighted distribution,非配資料.

  constraint mask_value         {(bad_fas) -> mask != 48'h0; (!bad_fas) -> mask == 48'h0;} //bad fas = 1. mask dont equal to 0 and do xor with fas byte.-> is implication constrain, it is equal !A//B. 這句話中表示若左面真的是 badfas,則右面mask一定能夠不為0. 若左面為goodfas 則右面mask一定為0

  function new(string name);

    super.new(name);

    setRandomizeControl(ON_TRANSACTION); //on transaction means random function will active when execute function begin.

  endfunction

  function void post_randomize();

    if(!frame_count_flag) begin

      this.max_lifecycle = random_frames;

    end

  endfunction

  function void setFrameCount(int frame_count);

    frame_count_flag = 1'b1;

    setMaxLifecycle(frame_count);

  endfunction   

  function void setRandomizeDist (int good_fas_dist, int bad_fas_dist);

    this.good_fas_dist = good_fas_dist;

    this.bad_fas_dist = bad_fas_dist;       // 把這個class裡面的bad_fas_dist給了setrandomizeddist中的bad—fas-dist。這個變量不再這個檔案中

  endfunction 

  function void execute(OTNFrame txn, ExecutionContext cntxt);

    if(!this.randomize()) `uvm_fatal("RANDOMIZATION_ERROR", "Failed to randomize FASPolicy")// 有random都需要這個語句來開始執行random function.

    `uvm_info("FASPolicy", $sformatf("bad_fas = %0d, mask = %0h", bad_fas, mask), UVM_MEDIUM)

    txn.getAlignment().setFAS(48'hf6f6f6282828 ^ mask); //因為mask是一個random,當mask為1 就開始破壞fas。

  endfunction

endclass

`endif //FASPolicy_sv

******************************************************************************************************************************************

******************************************************************************************************************************************/

下一部分是checker, 他負責檢查從dut出來的資料, 看看是否是正确的fasbyte.

下一個就是頂層的testcase,這個需要在questa 裡面運作

繼續閱讀