You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

axi_m_monitor.sv 3.6 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. class axi_m_monitor extends uvm_monitor;
  2. `uvm_component_utils(axi_m_monitor)
  3. // Components
  4. uvm_analysis_port#(axi_transaction#(D_WIDTH, A_WIDTH)) ap;
  5. virtual axi_intf#(.D_WIDTH(D_WIDTH), .A_WIDTH(A_WIDTH)).SMON vif;
  6. // variables
  7. axi_transaction#(D_WIDTH, A_WIDTH) w_trans, r_trans;
  8. bit w_done, r_done;
  9. int b_size;
  10. // Methods
  11. extern task run_mon(uvm_phase phase);
  12. extern task write_monitor();
  13. extern task read_monitor();
  14. function new(string name, uvm_component parent);
  15. super.new(name, parent);
  16. w_done = 1;
  17. r_done = 1;
  18. endfunction //new()
  19. // Function: build_phase
  20. extern function void build_phase(uvm_phase phase);
  21. // Function: run_phase
  22. extern task run_phase(uvm_phase phase);
  23. endclass //axi_m_monitor extends uvm_monitor
  24. function void axi_m_monitor::build_phase(uvm_phase phase);
  25. ap = new("ap", this);
  26. endfunction: build_phase
  27. task axi_m_monitor::run_phase(uvm_phase phase);
  28. forever begin
  29. run_mon(phase);
  30. @(vif.mon_cb);
  31. end
  32. endtask: run_phase
  33. task axi_m_monitor::run_mon(uvm_phase phase);
  34. fork
  35. if(w_done) begin
  36. phase.raise_objection(this);
  37. w_done = 0;
  38. write_monitor();
  39. w_done = 1;
  40. phase.drop_objection(this);
  41. end
  42. if(r_done) begin
  43. phase.raise_objection(this);
  44. r_done = 0;
  45. read_monitor();
  46. r_done = 1;
  47. phase.drop_objection(this);
  48. end
  49. join_none
  50. endtask: run_mon
  51. task axi_m_monitor::write_monitor();
  52. if(vif.mon_cb.AWVALID && vif.mon_cb.AWREADY) begin
  53. w_trans = axi_transaction#(D_WIDTH, A_WIDTH)::type_id::create("w_trans");
  54. w_trans.addr = vif.mon_cb.AWADDR;
  55. w_trans.id = vif.mon_cb.AWID;
  56. w_trans.b_size = vif.mon_cb.AWSIZE;
  57. w_trans.b_len = vif.mon_cb.AWLEN;
  58. w_trans.b_type = B_TYPE'(vif.mon_cb.AWBURST);
  59. w_trans.data = new [w_trans.b_len+1];
  60. for (int i=0; i<w_trans.b_len+1; i++) begin
  61. @(vif.mon_cb);
  62. wait(vif.mon_cb.WVALID && vif.mon_cb.WREADY);
  63. w_trans.data[i] = new [D_WIDTH/8];
  64. for (int j=0; j<D_WIDTH/8; j++) begin
  65. w_trans.data[i][j] = vif.mon_cb.WDATA[8*j+:8];
  66. end
  67. end
  68. wait(vif.mon_cb.BVALID);
  69. w_trans.b_resp = vif.mon_cb.BRESP;
  70. ap.write(w_trans);
  71. `uvm_info("MMON", $sformatf("WTRANS %s", w_trans.convert2string()), UVM_HIGH)
  72. end
  73. endtask: write_monitor
  74. task axi_m_monitor::read_monitor();
  75. if(vif.mon_cb.ARVALID && vif.mon_cb.ARREADY) begin
  76. r_trans = axi_transaction#(D_WIDTH, A_WIDTH)::type_id::create("r_trans");
  77. r_trans.addr = vif.mon_cb.ARADDR;
  78. r_trans.id = vif.mon_cb.ARID;
  79. r_trans.b_size = vif.mon_cb.ARSIZE;
  80. r_trans.b_len = vif.mon_cb.ARLEN;
  81. r_trans.b_type = B_TYPE'(vif.mon_cb.ARBURST);
  82. r_trans.data = new [r_trans.b_len+1];
  83. r_trans.r_resp = new [r_trans.b_len+1];
  84. for (int i=0; i<r_trans.b_len+1; i++) begin
  85. @(vif.mon_cb);
  86. wait(vif.mon_cb.RVALID && vif.mon_cb.RREADY);
  87. r_trans.data[i] = new [D_WIDTH/8];
  88. for (int j=0; j<D_WIDTH/8; j++) begin
  89. r_trans.data[i][j] = vif.mon_cb.RDATA[8*j+:8];
  90. end
  91. r_trans.r_resp[i] = vif.mon_cb.RRESP;
  92. end
  93. ap.write(r_trans);
  94. `uvm_info("MMON", $sformatf("RTRANS %s", r_trans.convert2string()), UVM_HIGH)
  95. end
  96. endtask: read_monitor