簡體   English   中英

Specman UVM:當值寫入另一個寄存器時,如何更新寄存器的值?

[英]Specman UVM: How update a value of a register when the value was written to another register?

(在我的驗證環境中,我們使用vr_ad包。)。 我嘗試實現下一個:當數據寫入其中一個寄存器( timer_load )時,應使用相同的數據更新另一個寄存器( timer_bgload )。

在UVM用戶指南中找到了下一個示例

// Attaching the target register file to the broadcasted register
extend ex_c_bus_env {
    post_generate() is also {
        xcore_regs.vr_ad_rx_data.attach(xbus_regs);
    };
};
// Implement the broadcast:
// When writing to register VR_AD_RX_DATA in XCORE vr_ad_reg_file,
// propagate the value to the VR_AD_XBUS_DATA register in ACTIVE_XBUS.
extend ACTIVE_XBUS vr_ad_reg_file {
    indirect_access( direction : vr_ad_rw_t, ad_item : vr_ad_base) is {
        if ad_item is a VR_AD_RX_DATA vr_ad_reg (d) {
            vr_ad_xbus_data.write_reg_val(d.get_cur_value());
        };
    };
};

我的寄存器:

reg_def TIMER_LOAD_0 TIMER 20'h00010 {
    reg_fld timer_load : uint (bits : 32) : RW : 0xffff;
};


reg_def TIMER_BGLOAD_0 TIMER 20'h00014 {
    reg_fld timer_bgload : uint (bits : 32) : RW : 0xffff;
};


reg_def TIMER_BGLOAD_1 TIMER 20'h00028 { 
    reg_fld timer_bgload : uint (bits : 32) : RW : 0xffff;
    //another reg with the same instance name
};

我將用於在將數據寫入tiemr_load之后更新timer_bgload寄存器的代碼

extend TIMER vr_ad_reg_file {
    indirect_access( direction : vr_ad_rw_t, ad_item : vr_ad_base) is {
        if ad_item is a TIMER_LOAD_0 vr_ad_reg (d) {
            timer_bgload.write_reg_val(d.get_cur_value());
        };
    };
};

unit timer_env_u like any_env {
    post_generate() is also {
        timer_regs.timer_load_0.attach(timer_regs.timer_bgload_0.timer_bgload);
    };  
};

我收到編譯錯誤

*** Error: No such variable 'timer_bgload'
                at line 17 in @timer_reg_db
            timer_bgload.write_reg_val(d.get_cur_value());

我非常感謝任何幫助。

您可以直接將timer_load寄存器附加到timer_load寄存器,並在timer_bgload實現indirect_access(...)

// attach the regs
extend TIMER vr_ad_reg_file {
  post_generate() is also {
    timer_load_0.attach(timer_bgload_0);
  }; 
};

// implement indirect_access()
extend TIMER_BGLOAD_0 vr_ad_reg {
  indirect_access(direction : vr_ad_rw_t, ad_item : vr_ad_base) is {
    if direction == WRITE and ad_item is a TIMER_LOAD_0 vr_ad_reg (d) {
      write_reg_val(d.get_cur_value());
    };
  };
};

我不知道為什么Cadence示例采用了將寄存器文件附加到間接寄存器的漫長路徑。

此外,如果您有多個TIMER_LOAD / BGLOAD寄存器(看起來您可能有2個),那么最好的辦法是首先定義類型:

// define register types without instantiation in reg_file
reg_def TIMER_LOAD {
  reg_fld timer_load : uint (bits : 32) : RW : 0xffff;
};

reg_def TIMER_BGLOAD {
  reg_fld timer_bgload : uint (bits : 32) : RW : 0xffff;
};

定義類型后,可以根據需要手動在寄存器文件中實例化它們。 看一下手冊,有一個例子向您展示如何做到這一點。

這意味着它足以在TIMER_BGLOAD子類型中實現indirect_access(...)方法(僅一次)而不是兩次(對於TIMER_BGLOAD_0TIMER_BGLOAD_1 )。

我用post_access實現它,類似的東西:

extend TIMER_LOAD_0 TIMER vr_ad_reg {
    post_access(operation : vr_ad_rw_t) is {
        if operation == WRITE {
            var rgf := get_access_path()[0].as_a(TIMER vr_ad_reg_file);
            rgf.timer_bgload_0.timer_bgload = timer_load;
        };
    };
};

注意,它可能不適用於第一次打擊。 如果不是,我會逐漸構建它,從這樣的'空'代碼開始:

extend TIMER_LOAD_0 TIMER vr_ad_reg {
    post_access(operation : vr_ad_rw_t) is {
        print me, operation;
    };
};

並在print語句中打開一個斷點,打開一個數據瀏覽器,查看我們在那里獲得的字段的確切名稱,嘗試從Specman CLI訪問它們 - 當它工作時 - 編碼回來。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM