:::info 分析测试点:

  1. WDOGCONTROL寄存器:
    1. INT使能和关闭;
    2. reset使能和关闭;

    3. :::

      对寄存器的各种状态进行了配置以后,covergroup什么时候做采样,做的采样是否准确十分重要。

对寄存器进行测试的时候covergroup不应该做采样,只有再做功能测试的时候才应该做采样。

8.1 reset、enable & reload test覆盖率收集

8.1.1 subscriber一侧代码

  1. `ifndef APB_WATCHDOG_SUBSCRIBER_SV
  2. `define APB_WATCHDOG_SUBSCRIBER_SV
  3. `uvm_analysis_imp_decl(_apb)
  4. class apb_watchdog_subscriber extends uvm_component;
  5. // analysis import
  6. uvm_analysis_imp_apb #(apb_transfer, apb_watchdog_subscriber) apb_trans_observed_imp;
  7. // Declare events
  8. uvm_event wdg_regacc_fd_e;
  9. uvm_event wdg_regacc_bd_e;
  10. uvm_event wdg_reg_inten_e;
  11. uvm_event wdg_reg_resen_e;
  12. uvm_event wdg_reg_load_e;
  13. uvm_event wdg_reg_intr_assert_e;
  14. uvm_event wdg_intrclr_e;
  15. protected uvm_event_pool _ep;
  16. apb_watchdog_config cfg;
  17. apb_watchdog_rgm rgm;
  18. virtual apb_watchdog_if vif;
  19. bit enable;
  20. `uvm_component_utils(apb_watchdog_subscriber)
  21. function new(string name = "apb_watchdog_subscriber", uvm_component parent);
  22. super.new(name, parent);
  23. endfunction
  24. function void build_phase(uvm_phase phase);
  25. super.build_phase(phase);
  26. apb_trans_observed_imp = new("apb_trans_observed_imp", this);
  27. // Get configuration from test layer
  28. if(!uvm_config_db#(apb_watchdog_config)::get(this, "", "cfg", cfg)) begin
  29. `uvm_fatal("GETCFG", "cannot get conifg object from config db")
  30. end
  31. vif = cfg.vif;
  32. rgm = cfg.rgm;
  33. // Local event pool and events creation
  34. _ep = new ("_ep");
  35. wdg_regacc_fd_e = _ep.get("wdg_regacc_fd_e");
  36. wdg_regacc_bd_e = _ep.get("wdg_regacc_bd_e");
  37. wdg_reg_inten_e = _ep.get("wdg_reg_inten_e");
  38. wdg_reg_resen_e = _ep.get("wdg_reg_resen_e");
  39. wdg_reg_load_e = _ep.get("wdg_reg_load_e");
  40. wdg_reg_intr_assert_e = _ep.get("wdg_reg_intr_assert_e");
  41. wdg_intrclr_e = _ep.get("wdg_intrclr_e");
  42. endfunction
  43. function void end_of_elaboration_phase(uvm_phase phase);
  44. super.end_of_elaboration_phase(phase);
  45. endfunction
  46. task run_phase(uvm_phase phase);
  47. super.run_phase(phase);
  48. do_events_trigger();
  49. do_listen_events();
  50. endtask
  51. virtual function void write_apb(apb_transfer tr);
  52. uvm_reg r;
  53. r = rgm.map.get_reg_by_offset(tr.addr);
  54. wdg_regacc_fd_e.trigger(r);
  55. endfunction
  56. virtual task do_events_trigger();
  57. uvm_object tmp;
  58. uvm_reg r;
  59. fork
  60. forever begin
  61. fork
  62. wdg_regacc_fd_e.wait_trigger_data(tmp);
  63. wdg_regacc_bd_e.wait_trigger_data(tmp);
  64. join_any
  65. disable fork;
  66. void'($cast(r, tmp));
  67. #1ps;
  68. if(r.get_name() == "WDOGCONTROL") begin
  69. if(rgm.WDOGCONTROL.INTEN.get() == 1'b1) wdg_reg_inten_e.trigger();
  70. if(rgm.WDOGCONTROL.RESEN.get() == 1'b1) wdg_reg_resen_e.trigger();
  71. end
  72. else if(r.get_name() == "WDOGLOAD") begin
  73. if(rgm.WDOGLOAD.LOADVAL.get() != 0) wdg_reg_load_e.trigger();
  74. end
  75. else if(r.get_name() == "WDOGINTCLR") begin
  76. if(rgm.WDOGINTCLR.INTCLR.get() == 1) wdg_intrclr_e.trigger();
  77. end
  78. end
  79. join_none
  80. endtask
  81. virtual task do_listen_events();
  82. endtask
  83. endclass
  84. `endif // APB_WATCHDOG_subscriber_SV

cov和scoreboard都继承于subscriber,subscriber的作用就是声明事件,触发,监听事件; 因此可以将监听事件在subscriber中声明,子类只需要继承即可。

8.1.2 cov一侧代码

  1. `ifndef APB_WATCHDOG_COV_SV
  2. `define APB_WATCHDOG_COV_SV
  3. class apb_watchdog_cov extends apb_watchdog_subscriber;
  4. `uvm_component_utils(apb_watchdog_cov)
  5. // Covergroup definition below
  6. // T1 Watchdog overall control
  7. // T1.1 Interrupt enable & disable(0 -> 1 & 1 -> 0);
  8. // T1.2 Reset enable & disable( 0-> 1 & 1 -> 0);
  9. covergroup apb_watchdog_t1_overall_control_cg with function sample (bit [31:0] val, string field);
  10. option.name = "T1 Watchdog overall control";
  11. INTEN : coverpoint val iff (field == "INTEN") {
  12. bins to_enable = (1'b0 => 1'b1);
  13. bins to_disale = (1'b1 => 1'b0);
  14. }
  15. endgroup
  16. // T2 Watchdog load & reload value
  17. // T2.1 Initial load (counter 0 -> load value)
  18. // T2.2 Load value to reload value (laod value -> reload value)
  19. // T2.3 load value range(min value, max value and others)
  20. covergroup apb_watchdog_t2_value_reload_value with function sample (bit [31:0] val);
  21. option.name = "T2 Wathcdog load & reload value";
  22. INLOAD : coverpoint val {
  23. bins iniload = (0 => [1:32'hFFFFFFFF]);
  24. }
  25. RELOAD : coverpoint val {
  26. bins reload = ([1:32'hFFFFFFFF] => [1:32'hFFFFFFFF]);
  27. }
  28. LOADRANGE : coverpoint val {
  29. bins min = {32'h1};
  30. bins max = {32'hFFFFFFFF};
  31. bins others = default;
  32. }
  33. endgroup
  34. function new (string name = "apb_watchdog_cov", uvm_component parent);
  35. super.new(name, parent);
  36. apb_watchdog_t1_overall_control_cg = new();
  37. apb_watchdog_t2_value_reload_value = new();
  38. endfunction
  39. function void build_phase(uvm_phase phase);
  40. super.build_phase(phase);
  41. endfunction
  42. task do_listen_events();
  43. uvm_object tmp;
  44. uvm_reg r;
  45. fork
  46. forever begin
  47. wait(cfg.cov_enable);
  48. wdg_regacc_e.wait_trigger_data(tmp);
  49. void'($cast(r, tmp));
  50. if(r.get_name() == "WDOGCONTROL") begin
  51. apb_watchdog_t1_overall_control_cg.sample(rgm.WDOGCONTROL.INTEN.get(), "INTEN");
  52. apb_watchdog_t1_overall_control_cg.sample(rgm.WDOGCONTROL.RESEN.get(), "RESEN");
  53. end
  54. else if(r.get_name() == "WDOGLOAD") begin
  55. apb_watchdog_t2_value_reload_value.sample(rgm.WDOGLOAD.LOADVAL.get());
  56. end
  57. end
  58. join_none
  59. endtask
  60. endclass
  61. `

8.1.3 更新 Makefile

【调试及结果】

:::info

  1. Terminal运行 :::
    1. make elab COV=1
    2. make run COV=1 GUI=1 TESTNAME=apb_watchdog_countdown_test seed=100
    运行完测试以后点击Terminate
    image.png

    可以看到,运行完测试以后的所有数据都在out目录下的db中

:::info

  1. 查看覆盖率(DVE自带) :::
    1. make mergecov
    2. make dvecov
    image.png

    搜索apb_watchdog_cov可以查看到我们定义的功能覆盖率,并没有采样到数据,结果发现采样的是一个从0到非0的一个状态变化,但是0这个状态没有采样下来,因此必须在采样的时候添加status。

:::info

  1. 查看功能覆盖率(Verdi模式) :::
    1. make verdicov
    image.png

    在Verdi中查看发现inten和load值的变化这个事件没有采到,只有采到初始的值以后才能采到发生变化的这个事件,因此需要对cov进行以下修改:

  1. `ifndef APB_WATCHDOG_COV_SV
  2. `define APB_WATCHDOG_COV_SV
  3. class apb_watchdog_cov extends apb_watchdog_subscriber;
  4. `uvm_component_utils(apb_watchdog_cov)
  5. // Covergroup definition below
  6. // T1 Watchdog overall control
  7. // T1.1 Interrupt enable & disable(0 -> 1 & 1 -> 0);
  8. // T1.2 Reset enable & disable( 0-> 1 & 1 -> 0);
  9. covergroup apb_watchdog_t1_overall_control_cg with function sample (bit [31:0] val, string field);
  10. option.name = "T1 Watchdog overall control";
  11. INTEN : coverpoint val iff (field == "INTEN") {
  12. bins stat_en = {1'b1};
  13. bins stat_dis = {1'b0};
  14. bins to_enable = (1'b0 => 1'b1);
  15. bins to_disale = (1'b1 => 1'b0);
  16. }
  17. endgroup
  18. // T2 Watchdog load & reload value
  19. // T2.1 Initial load (counter 0 -> load value)
  20. // T2.2 Load value to reload value (laod value -> reload value)
  21. // T2.3 load value range(min value, max value and others)
  22. covergroup apb_watchdog_t2_value_reload_value with function sample (bit [31:0] val);
  23. option.name = "T2 Wathcdog load & reload value";
  24. INLOAD : coverpoint val {
  25. bins iniload = (0 => [1:32'hFFFFFFFF]);
  26. }
  27. RELOAD : coverpoint val {
  28. bins reload = ([1:32'hFFFFFFFF] => [1:32'hFFFFFFFF]);
  29. }
  30. LOADRANGE : coverpoint val {
  31. bins min = {32'h1};
  32. bins max = {32'hFFFFFFFF};
  33. bins others = default;
  34. }
  35. endgroup
  36. function new (string name = "apb_watchdog_cov", uvm_component parent);
  37. super.new(name, parent);
  38. apb_watchdog_t1_overall_control_cg = new();
  39. apb_watchdog_t2_value_reload_value = new();
  40. endfunction
  41. function void build_phase(uvm_phase phase);
  42. super.build_phase(phase);
  43. endfunction
  44. task do_listen_events();
  45. uvm_object tmp;
  46. uvm_reg r;
  47. fork
  48. forever begin
  49. wait(cfg.cov_enable);
  50. wdg_regacc_e.wait_trigger_data(tmp);
  51. void'($cast(r, tmp));
  52. if(r.get_name() == "WDOGCONTROL") begin
  53. apb_watchdog_t1_overall_control_cg.sample(rgm.WDOGCONTROL.INTEN.get(), "INTEN");
  54. apb_watchdog_t1_overall_control_cg.sample(rgm.WDOGCONTROL.RESEN.get(), "RESEN");
  55. end
  56. else if(r.get_name() == "WDOGLOAD") begin
  57. apb_watchdog_t2_value_reload_value.sample(rgm.WDOGLOAD.LOADVAL.get());
  58. end
  59. end
  60. join_none
  61. endtask
  62. endclass
  63. `endif

在采样的时候对状态初始状态也进行采样

:::danger 【思考】

  1. 之前在事件触发器中,为了保证采样的稳定,添加了1ps以保证每次trigger出来的都是寄存器模型更新以后的值;
  2. 所以cov采样的时候采样到的是寄存器模型更新以后的值, ::: ``verilogifndef APB_WATCHDOG_REG_ENABLE_INTR_SV `define APB_WATCHDOG_REG_ENABLE_INTR_SV

    class apb_watchdog_reg_enable_intr extends apb_watchdog_element_base_seq;

    `uvm_object_utils(apb_watchdog_reg_enable_intr)

    function new(string name = “apb_watchdog_reg_enable_intr”); super.new(name); endfunction

    task body(); super.body(); uvm_info("body", "Entered...", UVM_LOW) rgm.WDOGCONTROL.mirror(status); rgm.WDOGCONTROL.INTEN.set(1'b1); rgm.WDOGCONTROL.update(status);uvm_info(“body”, “Exiting…”, UVM_LOW) endtask

    endclass

`endif //APB_WATCHDOG_REG_ENABLE_INTR

  1. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22348254/1654571225058-4500fbe2-ea61-4eca-805c-238c167c76fc.png#clientId=u9e46a4c0-008d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1042&id=u77eb9240&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1303&originWidth=2302&originalType=binary&ratio=1&rotation=0&showTitle=false&size=559223&status=done&style=none&taskId=u81fbf11b-3d41-4544-840e-fde28bb1d8b&title=&width=1841.6)
  2. > 当寄存器模型拿到通过mirror更新的值以后,还未进行采样就被set1,因此采样到的值就是1,但是此时期望采到的是初始的0状态。
  3. > 时刻是115001ps
  4. :::info
  5. 解决方法:
  6. 1. 修改RGMadapter,但是当对同一个寄存器进行操作的时候不建议这么做,因为会影响其他功能;
  7. 1. interface中添加delta cycle
  8. 1. 在两个seq中分别等待这个delta cycle
  9. :::
  10. ```verilog
  11. interface apb_watchdog_if;
  12. logic [3:0] ecorevnum = 4'b1011;
  13. logic wdog_int;
  14. logic wdog_res;
  15. logic apb_clk;
  16. logic apb_rstn;
  17. logic wdg_clk;
  18. logic wdg_rstn;
  19. task wait_apb(int n);
  20. repeat(n) @(posedge apb_clk);
  21. endtask
  22. task wait_wdg(int n);
  23. repeat(n) @(posedge wdg_clk);
  24. endtask
  25. endinterface
  1. `ifndef APB_WATCHDOG_REG_ENABLE_INTR_SV
  2. `define APB_WATCHDOG_REG_ENABLE_INTR_SV
  3. class apb_watchdog_reg_enable_intr extends apb_watchdog_element_base_seq;
  4. `uvm_object_utils(apb_watchdog_reg_enable_intr)
  5. function new(string name = "apb_watchdog_reg_enable_intr");
  6. super.new(name);
  7. endfunction
  8. task body();
  9. super.body();
  10. `uvm_info("body", "Entered...", UVM_LOW)
  11. rgm.WDOGCONTROL.mirror(status);
  12. vif.wait_apb(1);
  13. rgm.WDOGCONTROL.INTEN.set(1'b1);
  14. rgm.WDOGCONTROL.update(status);
  15. `uvm_info("body", "Exiting...", UVM_LOW)
  16. endtask
  17. endclass
  18. `endif //APB_WATCHDOG_REG_ENABLE_INTR
  1. `ifndef APB_WATCHDOG_REG_LOADCOUNT_SV
  2. `define APB_WATCHDOG_REG_LOADCOUNT_SV
  3. class apb_watchdog_reg_loadcount extends apb_watchdog_element_base_seq;
  4. rand bit[31:0] load_val;
  5. constraint load_cstr{
  6. soft load_val inside {['h1:'hFFFF]};
  7. }
  8. `uvm_object_utils(apb_watchdog_reg_loadcount)
  9. function new(string name = "apb_watchdog_reg_loadcount");
  10. super.new(name);
  11. endfunction
  12. task body();
  13. super.body();
  14. `uvm_info("body", "Entered...", UVM_LOW)
  15. rgm.WDOGLOAD.mirror(status);
  16. vif.wait_apb(1);
  17. rgm.WDOGLOAD.write(status, load_val);
  18. `uvm_info("body", "Exiting...", UVM_LOW)
  19. endtask
  20. endclass
  21. `endif //APB_WATCHDOG_REG_LOADCOUNT

分析: subscriber在拿到apb_transfer,1ps以后将事件trigger出来;采样发生在1ps的位置; 而seq中是在1ps+delta cycle的时间以后再对enable或load的值进行改变。

image.png
image.png

通过sample采样的方式只能采样到静态的值,对于动态变化的值没有办法进行有效采样

8.1.4 采用event来进行动态值的采样

  1. `ifndef APB_WATCHDOG_COV_SV
  2. `define APB_WATCHDOG_COV_SV
  3. class apb_watchdog_cov extends apb_watchdog_subscriber;
  4. bit [31:0] reg_field_value;
  5. event regacc_sve;
  6. `uvm_component_utils(apb_watchdog_cov)
  7. // Covergroup definition below
  8. // T1 Watchdog overall control
  9. // T1.1 Interrupt enable & disable(0 -> 1 & 1 -> 0);
  10. // T1.2 Reset enable & disable( 0-> 1 & 1 -> 0);
  11. covergroup apb_watchdog_t1_overall_control_cg with function sample (bit [31:0] val, string field);
  12. option.name = "T1 Watchdog overall control";
  13. INTEN : coverpoint val iff (field == "INTEN") {
  14. bins stat_en = {1'b1};
  15. bins stat_dis = {1'b0};
  16. bins to_enable = (1'b0 => 1'b1);
  17. bins to_disale = (1'b1 => 1'b0);
  18. }
  19. RESEN : coverpoint val iff (field == "RESEN") {
  20. bins stat_en = {1'b1};
  21. bins stat_dis = {1'b0};
  22. bins to_enable = (1'b0 => 1'b1);
  23. bins to_disable= (1'b1 => 1'b0);
  24. }
  25. endgroup
  26. covergroup apb_watchdog_t1_overall_control_clk_cg (ref bit [31:0] val) @(regacc_sve);
  27. option.name = "T1 Watchdog overall control";
  28. INTEN : coverpoint val[0]{
  29. bins stat_en = {1'b1};
  30. bins stat_dis = {1'b0};
  31. bins to_enable = (1'b0 => 1'b1);
  32. bins to_disale = (1'b1 => 1'b0);
  33. }
  34. RESEN : coverpoint val[1]{
  35. bins stat_en = {1'b1};
  36. bins stat_dis = {1'b0};
  37. bins to_enable = (1'b0 => 1'b1);
  38. bins to_disable= (1'b1 => 1'b0);
  39. }
  40. endgroup
  41. // T2 Watchdog load & reload value
  42. // T2.1 Initial load (counter 0 -> load value)
  43. // T2.2 Load value to reload value (laod value -> reload value)
  44. // T2.3 load value range(min value, max value and others)
  45. ...
  46. function new (string name = "apb_watchdog_cov", uvm_component parent);
  47. super.new(name, parent);
  48. apb_watchdog_t1_overall_control_cg = new();
  49. apb_watchdog_t2_value_reload_value = new();
  50. apb_watchdog_t1_overall_control_clk_cg = new(this.reg_field_value);
  51. endfunction
  52. function void build_phase(uvm_phase phase);
  53. super.build_phase(phase);
  54. endfunction
  55. task do_listen_events();
  56. uvm_object tmp;
  57. uvm_reg r;
  58. fork
  59. forever begin
  60. wait(cfg.cov_enable);
  61. wdg_regacc_e.wait_trigger_data(tmp);
  62. void'($cast(r, tmp));
  63. if(r.get_name() == "WDOGCONTROL") begin
  64. apb_watchdog_t1_overall_control_cg.sample(rgm.WDOGCONTROL.INTEN.get(), "INTEN");
  65. apb_watchdog_t1_overall_control_cg.sample(rgm.WDOGCONTROL.RESEN.get(), "RESEN");
  66. reg_field_value = rgm.WDOGCONTROL.get();
  67. ->regacc_sve;
  68. end
  69. else if(r.get_name() == "WDOGLOAD") begin
  70. apb_watchdog_t2_value_reload_value.sample(rgm.WDOGLOAD.LOADVAL.get());
  71. end
  72. end
  73. join_none
  74. endtask
  75. endclass
  76. `endif // APB_WATCHDOG_COV_SV

【调试及结果】

image.png

可以发现,对于状态的变化可以正常通过事件采到,注意要从寄存器模型中拿到值以后再进行采样。

8.2 集成测试覆盖率收集

在之前的APB寄存器直接访问中,对四个只读寄存器进行了读操作,这一部分cov的收集已经在RGM中完成,此处重点关注watchdog的功能覆盖率:

  1. `ifndef APB_WATCHDOG_COV_SV
  2. `define APB_WATCHDOG_COV_SV
  3. class apb_watchdog_cov extends apb_watchdog_subscriber;
  4. bit [31:0] reg_field_value;
  5. event regacc_sve;
  6. `uvm_component_utils(apb_watchdog_cov)
  7. ...
  8. // T3 Watchdog integration
  9. // T3.1 Initial int & res value;
  10. // T3.2 Int & res value after intergration mode enable
  11. covergroup apb_watchdog_t3_itcr_test_mode with function sample (bit [31:0] val, string field);
  12. option.name = "T3 Watchdog integration test";
  13. INTR_DISABLE : coverpoint val iff (field == "INTR_DISABLE"){
  14. bins inival = {1'b0};
  15. }
  16. INTR_ENABLE : coverpoint val iff (field == "INTR_ENABLE"){
  17. bins newval = {1'b1};
  18. }
  19. endgroup
  20. function new (string name = "apb_watchdog_cov", uvm_component parent);
  21. super.new(name, parent);
  22. apb_watchdog_t1_overall_control_cg = new();
  23. apb_watchdog_t2_value_reload_value = new();
  24. apb_watchdog_t1_overall_control_clk_cg = new(this.reg_field_value);
  25. apb_watchdog_t3_itcr_test_mode = new();
  26. endfunction
  27. function void build_phase(uvm_phase phase);
  28. super.build_phase(phase);
  29. endfunction
  30. task do_listen_events();
  31. uvm_object tmp;
  32. uvm_reg r;
  33. fork
  34. forever begin
  35. wait(cfg.cov_enable);
  36. wdg_regacc_e.wait_trigger_data(tmp);
  37. void'($cast(r, tmp));
  38. ...
  39. else if(r.get_name() == "WDOGITCR") begin
  40. if(rgm.WDOGITCR.ITME.get() == 1'b0) begin
  41. apb_watchdog_t3_itcr_test_mode.sample(rgm.WDOGITCR.ITME.get(), "INTR_DISABLE");
  42. apb_watchdog_t3_itcr_test_mode.sample(vif.wdog_int, "INTR_DISABLE");
  43. apb_watchdog_t3_itcr_test_mode.sample(vif.wdog_res, "INTR_DISABLE");
  44. end
  45. end
  46. else if(r.get_name() == "WDOGITOP") begin
  47. apb_watchdog_t3_itcr_test_mode.sample(rgm.WDOGITCR.ITME.get(), "INTR_ENABLE");
  48. apb_watchdog_t3_itcr_test_mode.sample(vif.wdog_int, "INTR_ENABLE");
  49. apb_watchdog_t3_itcr_test_mode.sample(vif.wdog_res, "INTR_ENABLE");
  50. end
  51. end
  52. join_none
  53. endtask
  54. endclass
  55. `endif // APB_WATCHDOG_COV_SV

image.png

8.3 中断使能及使能禁止测试覆盖率收集

  1. `ifndef APB_WATCHDOG_COV_SV
  2. `define APB_WATCHDOG_COV_SV
  3. class apb_watchdog_cov extends apb_watchdog_subscriber;
  4. bit [31:0] reg_field_value;
  5. event regacc_sve;
  6. `uvm_component_utils(apb_watchdog_cov)
  7. ...
  8. // T4 Disable interrupt test
  9. // T4.1 INT value after enable
  10. // T4.1 INT value after disable
  11. covergroup apb_watchdog_t4_intr_disable_test_mode with function sample (bit [31:0] val, string field);
  12. option.name = "T4 disable interrupt test";
  13. INT_ENABLE : coverpoint val iff (field == "INT_ENABLE"){
  14. bins state_en = {1'b1};
  15. }
  16. INT_DISABLE : coverpoint val iff (field == "INT_DISABLE"){
  17. bins state_dis = {1'b0};
  18. bins state_raw = {1'b1};
  19. bins state_msk = {1'b0};
  20. }
  21. endgroup
  22. function new (string name = "apb_watchdog_cov", uvm_component parent);
  23. super.new(name, parent);
  24. apb_watchdog_t1_overall_control_cg = new();
  25. apb_watchdog_t2_value_reload_value = new();
  26. apb_watchdog_t1_overall_control_clk_cg = new(this.reg_field_value);
  27. apb_watchdog_t3_itcr_test_mode = new();
  28. apb_watchdog_t4_intr_disable_test_mode = new();
  29. endfunction
  30. function void build_phase(uvm_phase phase);
  31. super.build_phase(phase);
  32. endfunction
  33. task do_listen_events();
  34. uvm_object tmp;
  35. uvm_reg r;
  36. fork
  37. forever begin
  38. wait(cfg.cov_enable);
  39. wdg_regacc_e.wait_trigger_data(tmp);
  40. void'($cast(r, tmp));
  41. if(r.get_name() == "WDOGCONTROL") begin
  42. apb_watchdog_t1_overall_control_cg.sample(rgm.WDOGCONTROL.INTEN.get(), "INTEN");
  43. apb_watchdog_t1_overall_control_cg.sample(rgm.WDOGCONTROL.RESEN.get(), "RESEN");
  44. reg_field_value = rgm.WDOGCONTROL.get();
  45. ->regacc_sve;
  46. apb_watchdog_t4_intr_disable_test_mode.sample(rgm.WDOGCONTROL.INTEN.get(), "INT_ENABLE");
  47. apb_watchdog_t4_intr_disable_test_mode.sample(rgm.WDOGMIS.INT.get(), "INT_ENABLE");
  48. apb_watchdog_t4_intr_disable_test_mode.sample(rgm.WDOGRIS.RAWINT.get(), "INT_ENABLE");
  49. apb_watchdog_t4_intr_disable_test_mode.sample(rgm.WDOGCONTROL.INTEN.get(), "INT_DISABLE");
  50. apb_watchdog_t4_intr_disable_test_mode.sample(rgm.WDOGMIS.INT.get(), "INT_DISABLE");
  51. apb_watchdog_t4_intr_disable_test_mode.sample(rgm.WDOGRIS.RAWINT.get(), "INT_DISABLE");
  52. end
  53. ...
  54. end
  55. join_none
  56. endtask
  57. endclass
  58. `endif // APB_WATCHDOG_COV_SV

image.png

8.4 寄存器上锁功能覆盖率收集

  1. `ifndef APB_WATCHDOG_COV_SV
  2. `define APB_WATCHDOG_COV_SV
  3. class apb_watchdog_cov extends apb_watchdog_subscriber;
  4. bit [31:0] reg_field_value;
  5. event regacc_sve;
  6. `uvm_component_utils(apb_watchdog_cov)
  7. ...
  8. // T5 Reg lock & unlock function test
  9. covergroup apb_watchdog_t5_reg_lock_test_mode with function sample (bit [31:0] val, string field);
  10. option.name = "T5 reg lock test";
  11. LOCK : coverpoint val iff (field == "LOCK"){
  12. bins lock_state = {1'b1};
  13. }
  14. UNLOCK : coverpoint val iff (field == "UNLOCK"){
  15. bins value = {'h1ACCE551};
  16. bins unlock_state = {1'b0};
  17. }
  18. endgroup
  19. function new (string name = "apb_watchdog_cov", uvm_component parent);
  20. super.new(name, parent);
  21. apb_watchdog_t1_overall_control_cg = new();
  22. apb_watchdog_t2_value_reload_value = new();
  23. apb_watchdog_t1_overall_control_clk_cg = new(this.reg_field_value);
  24. apb_watchdog_t3_itcr_test_mode = new();
  25. apb_watchdog_t4_intr_disable_test_mode = new();
  26. apb_watchdog_t5_reg_lock_test_mode = new();
  27. endfunction
  28. function void build_phase(uvm_phase phase);
  29. super.build_phase(phase);
  30. endfunction
  31. task do_listen_events();
  32. uvm_object tmp;
  33. uvm_reg r;
  34. fork
  35. forever begin
  36. wait(cfg.cov_enable);
  37. wdg_regacc_e.wait_trigger_data(tmp);
  38. void'($cast(r, tmp));
  39. ...
  40. else if(r.get_name() == "WDOGLOCK") begin
  41. apb_watchdog_t5_reg_lock_test_mode.sample(rgm.WDOGLOCK.get(), "LOCK");
  42. apb_watchdog_t5_reg_lock_test_mode.sample(rgm.WDOGLOCK.get(), "UNLOCK");
  43. end
  44. end
  45. join_none
  46. endtask
  47. endclass
  48. `endif // APB_WATCHDOG_COV_SV

image.png

运行寄存器上锁测试,最终覆盖率为100%