搭建文件框架

同样的,我们也是先将整个验证环境的框架搭建起来
image.png

ahb_gpio_config

  1. `ifndef AHB_GPIO_CONFIG_SV
  2. `define AHB_GPIO_CONFIG_SV
  3. class ahb_gpio_config extends uvm_object;
  4. int seq_check_count;
  5. int seq_check_error;
  6. int scb_check_count;
  7. int scb_check_error;
  8. bit scb_enable = 1;
  9. bit cov_enable = 1;
  10. ahb_agent_configuration ahb_cfg;
  11. virtual ahb_gpio_if vif;
  12. ahb_gpio_rgm rgm;
  13. `uvm_object_utils(ahb_gpio_config)
  14. // USER to specify the config items
  15. function new (string name = "ahb_gpio_config");
  16. super.new(name);
  17. ahb_cfg = ahb_agent_configuration::type_id::create("ahb_cfg");
  18. endfunction : new
  19. endclass
  20. `endif // AHB_GPIO_CONFIG_SV

ahb_gpio_cov

  1. `ifndef AHB_GPIO_COV_SV
  2. `define AHB_GPIO_COV_SV
  3. class ahb_gpio_cov extends ahb_gpio_subscriber;
  4. `uvm_component_utils(ahb_gpio_cov)
  5. function new (string name = "ahb_gpio_cov", uvm_component parent);
  6. super.new(name, parent);
  7. endfunction
  8. function void build_phase(uvm_phase phase);
  9. super.build_phase(phase);
  10. endfunction
  11. task do_listen_events();
  12. endtask
  13. virtual function void write(ahb_transaction tr);
  14. endfunction
  15. endclass
  16. `endif // AHB_GPIO_COV_SV

env

ahb_gpio_env

  1. `ifndef AHB_GPIO_ENV_SV
  2. `define AHB_GPIO_ENV_SV
  3. class ahb_gpio_env extends uvm_env;
  4. ahb_master_agent ahb_mst;
  5. ahb_gpio_config cfg;
  6. ahb_gpio_virtual_sequencer virt_sqr;
  7. ahb_gpio_rgm rgm;
  8. ahb_gpio_adapter adapter;
  9. uvm_reg_predictor #(ahb_transaction) predictor;
  10. ahb_gpio_cov cov;
  11. ahb_gpio_scoreboard scb;
  12. `uvm_component_utils(ahb_gpio_env)
  13. function new (string name = "ahb_gpio_env", uvm_component parent);
  14. super.new(name, parent);
  15. endfunction
  16. function void build_phase(uvm_phase phase);
  17. super.build_phase(phase);
  18. // Get configuration from test layer
  19. if(!uvm_config_db#(ahb_gpio_config)::get(this,"","cfg", cfg)) begin
  20. `uvm_fatal("GETCFG","cannot get config object from config DB")
  21. end
  22. uvm_config_db#(ahb_gpio_config)::set(this, "virt_sqr", "cfg", cfg);
  23. uvm_config_db#(ahb_gpio_config)::set(this, "cov", "cfg", cfg);
  24. uvm_config_db#(ahb_gpio_config)::set(this, "scb", "cfg", cfg);
  25. uvm_config_db#(ahb_agent_configuration)::set(this, "ahb_mst", "cfg", cfg.ahb_cfg);
  26. ahb_mst = ahb_master_agent::type_id::create("ahb_mst", this);
  27. virt_sqr = ahb_gpio_virtual_sequencer::type_id::create("virt_sqr", this);
  28. if(!uvm_config_db#(ahb_gpio_rgm)::get(this,"","rgm", rgm)) begin
  29. rgm = ahb_gpio_rgm::type_id::create("rgm", this);
  30. rgm.build();
  31. end
  32. uvm_config_db#(ahb_gpio_rgm)::set(this, "*", "rgm", rgm);
  33. adapter = ahb_gpio_adapter::type_id::create("adapter");
  34. predictor = uvm_reg_predictor#(ahb_transaction)::type_id::create("predictor", this);
  35. scb = ahb_gpio_scoreboard::type_id::create("scb", this);
  36. cov = ahb_gpio_cov::type_id::create("cov", this);
  37. endfunction
  38. function void connect_phase(uvm_phase phase);
  39. super.connect_phase(phase);
  40. virt_sqr.ahb_mst_sqr = ahb_mst.sequencer;
  41. rgm.map.set_sequencer(ahb_mst.sequencer, adapter);
  42. ahb_mst.monitor.item_observed_port.connect(predictor.bus_in);
  43. predictor.map = rgm.map;
  44. predictor.adapter = adapter;
  45. ahb_mst.monitor.item_observed_port.connect(cov.ahb_trans_observed_imp);
  46. ahb_mst.monitor.item_observed_port.connect(scb.ahb_trans_observed_imp);
  47. endfunction
  48. function void report_phase(uvm_phase phase);
  49. string reports = "\n";
  50. super.report_phase(phase);
  51. reports = {reports, $sformatf("================================================= \n")};
  52. reports = {reports, $sformatf("CURRENT TEST SUMMARY \n")};
  53. reports = {reports, $sformatf("SEQUENCE CHECK COUNT : %0d \n", cfg.seq_check_count)};
  54. reports = {reports, $sformatf("SEQUENCE CHECK ERROR : %0d \n", cfg.seq_check_error)};
  55. reports = {reports, $sformatf("SCOREBOARD CHECK COUNT : %0d \n", cfg.scb_check_count)};
  56. reports = {reports, $sformatf("SCOREBOARD CHECK COUNT : %0d \n", cfg.scb_check_error)};
  57. reports = {reports, $sformatf("================================================= \n")};
  58. `uvm_info("TEST_SUMMARY",reports, UVM_LOW);
  59. endfunction
  60. endclass
  61. `endif // AHB_GPIO_ENV_SV

ahb_gpio_pkg

  1. `ifndef AHB_GPIO_PKG_SV
  2. `define AHB_GPIO_PKG_SV
  3. package ahb_gpio_pkg;
  4. import uvm_pkg::*;
  5. `include "uvm_macros.svh"
  6. import ahb_pkg::*;
  7. `include "ahb_gpio_reg.sv"
  8. `include "ahb_gpio_config.sv"
  9. `include "ahb_gpio_adapter.sv"
  10. `include "ahb_gpio_subscriber.sv"
  11. `include "ahb_gpio_cov.sv"
  12. `include "ahb_gpio_scoreboard.sv"
  13. `include "ahb_gpio_virtual_sequencer.sv"
  14. `include "ahb_gpio_env.sv"
  15. `include "ahb_gpio_seq_lib.svh"
  16. `include "ahb_gpio_tests.svh"
  17. endpackage
  18. `endif // AHB_GPIO_PKG_SV

ahb_gpio_adapter

  1. `ifndef AHB_GPIO_ADAPTER_SV
  2. `define AHB_GPIO_ADAPTER_SV
  3. class ahb_gpio_adapter extends uvm_reg_adapter;
  4. `uvm_object_utils(ahb_gpio_adapter)
  5. function new(string name = "ahb_gpio_adapter");
  6. super.new(name);
  7. endfunction
  8. function uvm_sequence_item reg2bus(const ref uvm_reg_bus_op rw);
  9. endfunction
  10. function void bus2reg(uvm_sequence_item bus_item, ref uvm_reg_bus_op rw);
  11. endfunction
  12. endclass
  13. `endif //AHB_GPIO_ADAPTER_SV

ahb_gpio_subsriber

  1. `ifndef AHB_GPIO_SUBSCRIBER_SV
  2. `define AHB_GPIO_SUBSCRIBER_SV
  3. `uvm_analysis_imp_decl(_apb)
  4. class ahb_gpio_subscriber extends uvm_component;
  5. // analysis import
  6. uvm_analysis_imp #(ahb_transaction, ahb_gpio_subscriber) ahb_trans_observed_imp;
  7. // Declare events
  8. ahb_gpio_config cfg;
  9. virtual ahb_gpio_if vif;
  10. `uvm_component_utils(ahb_gpio_subscriber)
  11. function new(string name = "ahb_gpio_subscriber", uvm_component parent);
  12. super.new(name, parent);
  13. endfunction
  14. function void build_phase(uvm_phase phase);
  15. super.build_phase(phase);
  16. ahb_trans_observed_imp = new("ahb_trans_observed_imp", this);
  17. // Get configuration from test layer
  18. if(!uvm_config_db#(ahb_gpio_config)::get(this, "", "cfg", cfg)) begin
  19. `uvm_fatal("GETCFG", "cannot get conifg object from config db")
  20. end
  21. vif = cfg.vif;
  22. endfunction
  23. task run_phase(uvm_phase phase);
  24. super.run_phase(phase);
  25. do_events_trigger();
  26. do_listen_events();
  27. endtask
  28. virtual function void write(ahb_transaction tr);
  29. endfunction
  30. virtual task do_events_trigger();
  31. endtask
  32. virtual task do_listen_events();
  33. endtask
  34. endclass
  35. `endif // AHB_GPIO_SUBSCRIBER_SV

ahb_gpio_scoreboard

  1. `ifndef AHB_GPIO_SCOREBOARD_SV
  2. `define AHB_GPIO_SCOREBOARD_SV
  3. class ahb_gpio_scoreboard extends ahb_gpio_subscriber;
  4. bit [31:0] mem [int unsigned];
  5. // Events of scoreboard
  6. `uvm_component_utils(ahb_gpio_scoreboard)
  7. function new (string name = "ahb_gpio_scoreboard", uvm_component parent);
  8. super.new(name, parent);
  9. endfunction
  10. function void build_phase(uvm_phase phase);
  11. super.build_phase(phase);
  12. endfunction
  13. task run_phase(uvm_phase phase);
  14. super.run_phase(phase);
  15. do_data_check();
  16. endtask
  17. virtual function void write(ahb_transaction tr);
  18. endfunction
  19. task do_listen_events();
  20. endtask
  21. virtual task do_data_check();
  22. endtask
  23. endclass
  24. `endif // AHB_GPIO_SCOREBOARD_SV

reg

ahb_gpio_reg

  1. `ifndef AHB_GPIO_REG_SV
  2. `define AHB_GPIO_REG_SV
  3. class ahb_gpio_rgm extends uvm_reg_block;
  4. `uvm_object_utils(ahb_gpio_rgm)
  5. uvm_reg_map map;
  6. function new (string name = "ahb_gpio_rgm");
  7. super.new(name, UVM_NO_COVERAGE);
  8. endfunction
  9. virtual function build();
  10. map = create_map("map", 'h0, 4, UVM_LITTLE_ENDIAN);
  11. lock_model();
  12. endfunction
  13. endclass
  14. `endif // AHB_GPIO_REG_SV

seq_lib

elem_seqs

ahb_element_sequences

  1. `ifndef AHB_GPIO_ELEMENT_SEQUENCES_SVH
  2. `define AHB_GPIO_ELEMENT_SEQUENCES_SVH
  3. `include "ahb_gpio_element_base_seq.sv"
  4. `include "ahb_gpio_single_write_seq.sv"
  5. `include "ahb_gpio_single_read_seq.sv"
  6. `endif // AHB_GPIO_ELEMENT_SEQUENCES_SVH

ahb_gpio_element_base_seq

  1. `ifndef AHB_GPIO_ELEMENT_BASE_SEQ_SV
  2. `define AHB_GPIO_ELEMENT_BASE_SEQ_SV
  3. class ahb_gpio_element_base_seq extends uvm_sequence;
  4. ahb_gpio_config cfg;
  5. virtual ahb_gpio_if vif;
  6. ahb_gpio_rgm rgm;
  7. bit [31:0] rd_val, wr_val;
  8. uvm_status_e status;
  9. `uvm_object_utils(ahb_gpio_element_base_seq)
  10. `uvm_declare_p_sequencer(ahb_gpio_virtual_sequencer)
  11. function new(string name = "ahb_gpio_element_base_seq");
  12. super.new(name);
  13. endfunction
  14. virtual task body();
  15. `uvm_info("body","Entered...",UVM_LOW)
  16. //Get cfg from p_sequencer
  17. cfg = p_sequencer.cfg;
  18. vif = cfg.vif;
  19. rgm = cfg.rgm;
  20. `uvm_info("body","Exiting...",UVM_LOW)
  21. endtask
  22. virtual function void compare_data(logic[31:0] val1, logic[31:0] val2);
  23. cfg.seq_check_count++;
  24. if(val1 === val2)
  25. `uvm_info("CMPSUC", $sformatf("val1 'h%0x === val2 'h%0x", val1, val2), UVM_LOW)
  26. else begin
  27. cfg.seq_check_error++;
  28. `uvm_error("CMPSUC", $sformatf("val1 'h%0x !== val2 'h%0x", val1, val2))
  29. end
  30. endfunction
  31. endclass
  32. `endif //AHB_GPIO_ELEMENT_BASE_SEQ_SV

ahb_gpio_seq_lib.svh

  1. `ifndef AHB_GPIO_SEQ_LIB_SVH
  2. `define AHB_GPIO_SEQ_LIB_SVH
  3. `include "ahb_gpio_element_sequences.svh"
  4. `include "ahb_gpio_base_virt_seq.sv"
  5. `include "ahb_gpio_portout_set_virt_seq.sv"
  6. `endif // AHB_GPIO_SEQ_LIB_SVH

ahb_gpio_base_virt_seq

  1. `ifndef AHB_GPIO_BASE_VIRT_SEQ_SV
  2. `define AHB_GPIO_BASE_VIRT_SEQ_SV
  3. class ahb_gpio_base_virt_seq extends uvm_sequence;
  4. ahb_gpio_config cfg;
  5. virtual ahb_gpio_if vif;
  6. ahb_gpio_rgm rgm;
  7. bit [31:0] rd_val, wr_val;
  8. uvm_status_e status;
  9. // declaration of element sequence
  10. ahb_gpio_single_write_seq single_write;
  11. ahb_gpio_single_read_seq single_read;
  12. `uvm_object_utils(ahb_gpio_base_virt_seq)
  13. `uvm_declare_p_sequencer(ahb_gpio_virtual_sequencer)
  14. function new(string name = "ahb_gpio_base_virt_seq");
  15. super.new(name);
  16. endfunction
  17. virtual task body();
  18. `uvm_info("body","Entered...",UVM_LOW)
  19. //Get cfg from p_sequencer
  20. cfg = p_sequencer.cfg;
  21. vif = cfg.vif;
  22. rgm = cfg.rgm;
  23. wait_ready_for_stim();
  24. // TO do in sub_class
  25. `uvm_info("body","Exiting...",UVM_LOW)
  26. endtask
  27. virtual function void compare_data(logic[31:0] val1, logic[31:0] val2);
  28. cfg.seq_check_count++;
  29. if(val1 === val2)
  30. `uvm_info("CMPSUC", $sformatf("val1 'h%0x === val2 'h%0x", val1, val2), UVM_LOW)
  31. else begin
  32. cfg.seq_check_error++;
  33. `uvm_error("CMPSUC", $sformatf("val1 'h%0x !== val2 'h%0x", val1, val2))
  34. end
  35. endfunction
  36. task wait_reset_asserted();
  37. @(posedge vif.rst_n);
  38. endtask
  39. task wait_reset_released();
  40. @(negedge vif.rst_n);
  41. endtask
  42. task wait_cycles(int n = 1);
  43. repeat(n) @(posedge vif.clk);
  44. endtask
  45. task wait_ready_for_stim();
  46. wait_reset_released();
  47. wait_cycles(10);
  48. endtask
  49. endclass
  50. `endif //AHB_GPIO_BASE_VIRT_SEQ

test

ahb_gpio_base_test

  1. `ifndef AHB_GPIO_BASE_TEST_SV
  2. `define AHB_GPIO_BASE_TEST_SV
  3. virtual class ahb_gpio_base_test extends uvm_test;
  4. ahb_gpio_config cfg;
  5. ahb_gpio_env env;
  6. ahb_gpio_rgm rgm;
  7. function new(string name = "ahb_gpio_base_test", uvm_component parent);
  8. super.new(name, parent);
  9. endfunction
  10. function void build_phase(uvm_phase phase);
  11. super.build_phase(phase);
  12. rgm = ahb_gpio_rgm::type_id::create("rgm");
  13. rgm.build();
  14. uvm_config_db#(ahb_gpio_rgm)::set(this, "env", "rgm", rgm);
  15. cfg = ahb_gpio_config::type_id::create("cfg");
  16. cfg.rgm = rgm;
  17. // do pagpioeter configuration
  18. cfg.addr_start = 32'h0;
  19. cfg.addr_end = 32'h0000_FFFF;
  20. if(!uvm_config_db#(virtual ahb_gpio_if)::get(this,"","vif", cfg.vif)) begin
  21. `uvm_fatal("GETCFG","cannot get virtual interface from config DB")
  22. end
  23. uvm_config_db#(ahb_gpio_config)::set(this, "env", "cfg", cfg);
  24. env = ahb_gpio_env::type_id::create("env", this);
  25. endfunction
  26. function void connect_phase(uvm_phase phase);
  27. super.connect_phase(phase);
  28. endfunction
  29. task run_phase(uvm_phase phase);
  30. super.run_phase(phase);
  31. phase.phase_done.set_drain_time(this, 1us);
  32. phase.raise_objection(this);
  33. phase.drop_objection(this);
  34. endtask
  35. endclass
  36. `endif //AHB_GPIO_BASE_TEST

ahb_gpio_portout_set_test

  1. `ifndef AHB_RAM_SMOKE_TEST_SV
  2. `define AHB_RAM_SMOKE_TEST_SV
  3. class ahb_ram_smoke_test extends ahb_ram_base_test;
  4. `uvm_component_utils(ahb_ram_smoke_test)
  5. function new(string name = "ahb_ram_smoke_test", uvm_component parent);
  6. super.new(name, parent);
  7. endfunction
  8. function void build_phase(uvm_phase phase);
  9. super.build_phase(phase);
  10. endfunction
  11. task run_phase(uvm_phase phase);
  12. ahb_ram_smoke_virt_seq seq = ahb_ram_smoke_virt_seq::type_id::create("this");
  13. super.run_phase(phase);
  14. phase.raise_objection(this);
  15. seq.start(env.virt_sqr);
  16. phase.drop_objection(this);
  17. endtask
  18. endclass
  19. `endif //AHB_RAM_SMOKE_TEST_SV

tb

ahb_gpio_if

  1. `ifndef AHB_GPIO_IF_SV
  2. `define AHB_GPIO_IF_SV
  3. interface ahb_gpio_if;
  4. logic clk;
  5. logic rst_n;
  6. initial begin : rst_n_gen
  7. assert_reset(10);
  8. end
  9. task automatic assert_reset(int nclks = 1, int delay = 0);
  10. #(delay * 1ns);
  11. repeat(nclks) @(posedge clk);
  12. rst_n <= 0;
  13. repeat(5) @(posedge clk);
  14. rst_n <= 1;
  15. endtask
  16. endinterface
  17. `endif // AHB_GPIO_IF_SV

ahb_gpio_tb

当我们完成了上述的这些步骤以后,接下来就需要搭建编辑tb文件了,完成tb和DUT端口的连接:

  1. `ifndef AHB_RAM_TB_SV
  2. `define AHB_RAM_TB_SV
  3. module ahb_ram_tb;
  4. import uvm_pkg::*;
  5. `include "uvm_macros.svh"
  6. import ahb_ram_pkg::*;
  7. logic clk;
  8. logic rst_n;
  9. initial begin : generate_clk
  10. clk = 0;
  11. forever #2ns clk = !clk;
  12. end
  13. // AHB_RAM -> AHB_GPIO
  14. ahb_blockram_32 #(.ADDRESSWIDTH(16)) dut(
  15. .HCLK (ahb_if.hclk),
  16. .HRESETn (ahb_if.hreset_n),
  17. .HSELBRAM (1'b1),
  18. .HREADY (ahb_if.hready),
  19. .HTRANS (ahb_if.htrans),
  20. .HSIZE (ahb_if.hsize),
  21. .HWRITE (ahb_if.hwrite),
  22. .HADDR (ahb_if.haddr),
  23. .HWDATA (ahb_if.hwdata),
  24. .HREADYOUT (ahb_if.hready),
  25. .HRESP (ahb_if.hresp),
  26. .HRDATA (ahb_if.hrdata)
  27. );
  28. module cmsdk_ahb_gpio
  29. #(// Parameter to define valid bit pattern for Alternate functions
  30. // If an I/O pin does not have alternate function its function mask
  31. // can be set to 0 to reduce gate count.
  32. //
  33. // By default every bit can have alternate function
  34. parameter ALTERNATE_FUNC_MASK = 16'hFFFF,
  35. // Default alternate function settings
  36. parameter ALTERNATE_FUNC_DEFAULT = 16'h0000,
  37. // By default use little endian
  38. parameter BE = 0
  39. )
  40. // ----------------------------------------------------------------------------
  41. // Port Definitions
  42. // ----------------------------------------------------------------------------
  43. (// AHB Inputs
  44. .HCLK, (ahb_if.hclk) // system bus clock
  45. .HRESETn, (ahb_if.hreset_n) // system bus reset
  46. .FCLK, (ahb_if.hclk) // system bus clock
  47. .HSEL, (1'b1) // AHB peripheral select
  48. .HREADY, (ahb_if.hready) // AHB ready input
  49. .HTRANS, (ahb_if.htrans) // AHB transfer type
  50. .HSIZE, (ahb_if.hsize) // AHB hsize
  51. .HWRITE, (ahb_if.hwrite) // AHB hwrite
  52. .HADDR, (ahb_if.haddr) // AHB address bus
  53. .HWDATA, (ahb_if.hwdata) // AHB write data bus
  54. .ECOREVNUM, (4'b0110) // Engineering-change-order revision bits
  55. .PORTIN, (ahb_gpio_if.portin) // GPIO Interface input
  56. .HREADYOUT, (ahb_if.hready) // AHB ready output to S->M mux
  57. .HRESP, (ahb_if.hresp) // AHB response
  58. .HRDATA, (ahb_if.hrdata)
  59. .PORTOUT, (ahb_gpio_if.portout) // GPIO output
  60. .PORTEN, (ahb_gpio_if.porten) // GPIO output enable
  61. .PORTFUNC, (ahb_gpio_if.portfunc) // Alternate function control
  62. .GPIOINT, (ahb_gpio_if.gpioint) // Interrupt output for each pin
  63. .COMBINT (ahb_gpio_if.combint) // Combined interrupt
  64. );
  65. // ----------------------------------------------------------------------------
  66. // Internal wires
  67. // ----------------------------------------------------------------------------
  68. wire [31:0] IORDATA; // I/0 read data bus
  69. wire IOSEL; // Decode for peripheral
  70. wire [11:0] IOADDR; // I/O transfer address
  71. wire IOWRITE; // I/O transfer direction
  72. wire [1:0] IOSIZE; // I/O transfer size
  73. wire IOTRANS; // I/O transaction
  74. wire [31:0] IOWDATA; // I/O write data bus
  75. ahb_if ahb_if();
  76. assign ahb_if.hclk = clk;
  77. assign ahb_if.hreset_n = rst_n;
  78. assign ahb_if.hgrant = 1'b1;
  79. ahb_ram_if ahb_ram_if();
  80. assign ahb_ram_if.hclk = clk;
  81. assign ahb_ram_if.fclk = clk;
  82. assign rst_n = ahb_ram_if.rst_n;
  83. initial begin
  84. uvm_config_db #(virtual ahb_if)::set(uvm_root::get(), "uvm_test_top.env.ahb_mst", "vif", ahb_if);
  85. uvm_config_db #(virtual ahb_ram_if)::set(uvm_root::get(), "uvm_test_top", "vif", ahb_ram_if);
  86. uvm_config_db #(virtual ahb_ram_if)::set(uvm_root::get(), "uvm_test_top.env", "vif", ahb_ram_if);
  87. uvm_config_db #(virtual ahb_ram_if)::set(uvm_root::get(), "uvm_test_top.env.virt_sqr", "vif", ahb_ram_if);
  88. run_test();
  89. end
  90. endmodule
  91. `endif // AHB_RAM_TB_SV
  • 在连接的过程中,我们可以将DUT中左边与AHB相关的,将他们的信号连接到ahb_if中的信号中,DUT右边的信号与AHB协议没有关系,因此我们需要在当前这个模块的if中声明这些信号并将他们进行连接;
  • 另外我们需要注意的就是:

在整个GPIO的模块中是有hclk和fclk两个时钟的,所以我们需要在ahb_gpio_if中声明这两个信号并将他们与tb中的时钟信号进行连接。

后面的括号中放置的一些我们用于端口中的典型的特征值,因此我们不需要修改,直接使用设计代码中的默认值即可

Makefile & 查看波形文件

最后我们重新编辑一下makefile文件,并在sim_run.do文件中放入该波形文件的名称:

  1. #############################
  2. # User variables
  3. #############################
  4. TB = ahb_gpio_tb
  5. SEED = 1
  6. GUI ?= 0
  7. COV ?= 0
  8. DOTCL ?= 1
  9. VERB ?= UVM_HIGH
  10. OUT ?= out
  11. TESTNAME ?= ahb_gpio_portout_set_test
  12. DFILES = ../../verilog/{cmsdk_ahb_gpio.v,cmsdk_ahb_to_iop.v,cmsdk_iop_gpio.v}
  13. VFILES += ../vip_lib/ahb_pkg/ahb_pkg.sv \
  14. ../vip_lib/ahb_pkg/ahb_if.sv \
  15. ../env/ahb_gpio_pkg.sv \
  16. ../tb/ahb_gpio_if.sv \
  17. ../tb/ahb_gpio_tb.sv
  18. #############################
  19. # Environment variables
  20. #############################
  21. VCOMP_INC = +incdir+../../verilog \
  22. +incdir+../vip_lib/ahb_pkg/{.,sequence_lib} \
  23. +incdir+../{cfg,cov,reg,env,seq_lib,seq_lib/elem_seqs,test}
  24. VCOMP = vlogan -full64 -ntb_opts uvm-1.2 -sverilog -timescale=1ps/1ps -nc -l $(OUT)/log/comp.log $(VCOMP_INC)
  25. ELAB = vcs -full64 -ntb_opts uvm-1.2 -debug_acc+all -l $(OUT)/log/elab.log -sim_res=1ps
  26. RUN = $(OUT)/obj/$(TB).simv -l run.log -sml +ntb_random_seed=$(SEED) +UVM_TESTNAME=$(TESTNAME) +UVM_VERBOSITY=$(VERB) -cm_dir $(CM_DIR) -cm_name $(CM_NAME)
  27. COV_OPTS = -full64 -dir $(CM_DIR)
  28. CM_DIR ?= $(OUT)/cov.vdb
  29. CM_NAME ?= $(TESTNAME)_$(SEED)
  30. SIMRUNFILE = ahb_gpio_sim_run.do
  31. ifeq ($(GUI),1)
  32. RUN += -gui
  33. endif
  34. ifeq ($(DOTCL),1)
  35. RUN += -ucli -do $(SIMRUNFILE)
  36. endif
  37. ifeq ($(COV),1)
  38. ELAB += -cm line+cond+fsm+tgl+branch+assert -cm_dir $(CM_DIR)
  39. RUN += -cm line+cond+fsm+tgl+branch+assert -covg_cont_on_error
  40. endif
  41. prepare:
  42. mkdir -p $(OUT)/work
  43. mkdir -p $(OUT)/log
  44. mkdir -p $(OUT)/sim
  45. mkdir -p $(OUT)/obj
  46. mkdir -p .shadow
  47. comp: prepare
  48. $(VCOMP)
  49. $(VCOMP) $(DFILES) $(VFILES)
  50. elab: comp
  51. $(ELAB) -top $(TB) -o $(OUT)/obj/$(TB).simv
  52. run:
  53. $(RUN)
  54. mergecov:
  55. urg -format both $(COV_OPTS)
  56. dvecov:
  57. dve $(COV_OPTS)
  58. verdicov:
  59. verdi -cov -covdir $(CM_DIR)
  60. htmlcov:
  61. firefox urgReport/dashboard.html
  62. clean:
  63. rm -rf $(OUT) 64 AN.DB DVEfiles csrc *.simv *.simv.daidir *.simv.vdb ucli.key
  64. rm -rf *.log* *.vpd *.h urgReport

【调试及结果】

image.png
image.png
我们运行默认的ahb_gpio_portout_set_test,运行之后打打开uvm_debug,可以发现没有错误出现且所有phase均正常运行。