AXI-Verification architecture, functional coverage and assertions based coverage code
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.

394 lines
8.6 KiB

  1. class driver extends uvm_driver #(packet);
  2. `uvm_component_utils(driver)
  3. virtual axi_if vif;
  4. int data_bus_byte;
  5. packet write_address_queue [$];
  6. packet write_address;
  7. packet write_data_queue [$];
  8. packet write_data;
  9. packet write_response_queue [$];
  10. packet read_address_queue [$];
  11. packet read_address;
  12. packet read_data_response_queue [$];
  13. packet read_data;
  14. semaphore write_address_sema = new (1);
  15. semaphore write_data_sema = new (1);
  16. semaphore write_data_sema_1 = new (1);
  17. semaphore write_response_sema = new (1);
  18. semaphore write_response_sema_1 = new (1);
  19. semaphore read_address_sema = new (1);
  20. semaphore read_data_response_sema = new (1);
  21. semaphore read_data_response_sema_1 = new (1);
  22. extern function new (string name = "driver", uvm_component parent);
  23. extern function void build_phase (uvm_phase phase);
  24. extern function void connect_phase (uvm_phase phase);
  25. extern task run_phase (uvm_phase phase);
  26. extern task send_to_dut ();
  27. extern task write_address_channel ();
  28. extern task write_data_channel ();
  29. extern task fixed_burst ();
  30. extern task incr_burst();
  31. extern task write_response_channel ();
  32. extern task read_address_channel ();
  33. extern task read_data_response_channel ();
  34. extern task rd_incr_burst();
  35. endclass
  36. //////////////////////////////////////// NEW FUNCTION
  37. function driver::new (string name = "driver", uvm_component parent);
  38. super.new (name,parent);
  39. endfunction
  40. /////////////////////////////////////// BUILD PHASE
  41. virtual function void build_phase(uvm_phase phase);
  42. super.build_phase(phase);
  43. pkt=packet::type_id::create("pkt");
  44. if(!uvm_config_db#(virtual axi_if)::get(this,"","vif",vif))
  45. `uvm_error("drv","Unable to access Interface");
  46. endfunction
  47. ///////////////////////////////////////////////////// RUN PHASE
  48. task driver::run_phase (uvm_phase phase);
  49. forever
  50. begin
  51. seq_item_port.get_next_item(req);
  52. send_to_dut();
  53. seq_item_port.item_done();
  54. end
  55. endtask
  56. /////////////////////////////////////// SEND TO DUT
  57. task driver::send_to_dut ();
  58. write_address_queue.push_back (req);
  59. write_data_queue.push_back (req);
  60. write_response_queue.push_back (req);
  61. read_address_queue.push_back (req);
  62. read_data_response_queue.push_back(req);
  63. fork
  64. write_address_channel();
  65. write_data_channel();
  66. write_response_channel();
  67. read_address_channel ();
  68. read_data_response_channel ();
  69. join_any
  70. endtask
  71. /////////////////////////////////////// WRITE ADDRESS CHANNEL
  72. task driver::write_address_channel();
  73. write_address_sema.get(1);
  74. write_address = write_address_queue.pop_front();
  75. @(vif.mas_dr);
  76. req.control = 1;
  77. `uvm_info("MASTER_DRIVER",$sformatf("PRINTING FROM DRIVER \n %s",write_address.sprint()),UVM_HIGH)
  78. vif.mas_dr.awid <= write_address.awid;
  79. vif.mas_dr.awaddr <= write_address.awaddr;
  80. vif.mas_dr.awlen <= write_address.awlen;
  81. vif.mas_dr.awsize <= write_address.awsize;
  82. vif.mas_dr.awburst <= write_address.awburst;
  83. vif.mas_dr.awvalid <= 1;
  84. @(vif.mas_dr);
  85. wait (vif.mas_dr.awready);
  86. vif.mas_dr.awvalid <= 0;
  87. write_data_sema.put(1);
  88. write_address_sema.put(1);
  89. repeat(2)
  90. @(vif.mas_dr);
  91. endtask
  92. //////////////////////////////////////// WRITE DATA CHANNEL
  93. task driver::write_data_channel();
  94. write_data_sema.get(2);
  95. write_data_sema_1.get(1);
  96. write_data = write_data_queue.pop_front();
  97. @(vif.mas_dr);
  98. write_data.control = 2;
  99. `uvm_info("MASTER_DRIVER",$sformatf("PRINTING FROM DRIVER \n %s",write_data.sprint()),UVM_HIGH)
  100. case (write_data.awburst)
  101. 2'b00 : fixed_burst;
  102. 2'b01 : incr_burst;
  103. 2'b10 : incr_burst;
  104. endcase
  105. write_data_sema.put(1);
  106. write_data_sema_1.put(1);
  107. write_response_sema.put(1);
  108. read_address_sema.put(1);
  109. endtask
  110. /////////////////////////////////////// INCREMENT BURST
  111. task driver::incr_burst();
  112. foreach(write_data.wdata[i])
  113. begin
  114. case (write_data.wstrobe[i])
  115. 4'b0001 : vif.mas_dr.wdata [7:0] <= write_data.wdata[i];
  116. 4'b0010 : vif.mas_dr.wdata [15:8] <= write_data.wdata[i];
  117. 4'b0100 : vif.mas_dr.wdata [23:16] <= write_data.wdata[i];
  118. 4'b1000 : vif.mas_dr.wdata [31:24] <= write_data.wdata[i];
  119. 4'b0011 : vif.mas_dr.wdata [15:0] <= write_data.wdata[i];
  120. 4'b1100 : vif.mas_dr.wdata [31:16] <= write_data.wdata[i];
  121. 4'b1110 : vif.mas_dr.wdata [31:8] <= write_data.wdata[i];
  122. 4'b1111 : vif.mas_dr.wdata <= write_data.wdata[i];
  123. endcase
  124. vif.mas_dr.wstrobe <= write_data.wstrobe[i];
  125. vif.mas_dr.wid <= write_data.wid;
  126. if (i == write_data.burst_len - 1)
  127. vif.mas_dr.wlast <= 1;
  128. else
  129. vif.mas_dr.wlast <= 0;
  130. vif.mas_dr.wvalid <= 1;
  131. @(vif.mas_dr);
  132. wait (vif.mas_dr.wready);
  133. vif.mas_dr.wlast <= 0;
  134. vif.mas_dr.wvalid <= 0;
  135. @(vif.mas_dr);
  136. end
  137. endtask
  138. /////////////////////////////////////// FIXED BURST
  139. task driver::fixed_burst ();
  140. foreach(write_data.wdata[i])
  141. begin
  142. case (write_data.awsize)
  143. 2'b00 : vif.mas_dr.wdata[7:0] <= write_data.wdata[i];
  144. 2'b01 : vif.mas_dr.wdata[15:0] <= write_data.wdata[i];
  145. 2'b10 : vif.mas_dr.wdata[31:0] <= write_data.wdata[i];
  146. endcase
  147. vif.mas_dr.wid <= write_data.wid;
  148. if (i == write_data.burst_len - 1)
  149. vif.mas_dr.wlast <= 1;
  150. else
  151. vif.mas_dr.wlast <= 0;
  152. vif.mas_dr.wvalid <= 1;
  153. @(vif.mas_dr);
  154. wait (vif.mas_dr.wready);
  155. vif.mas_dr.wlast <= 0;
  156. vif.mas_dr.wvalid <= 0;
  157. @(vif.mas_dr);
  158. end
  159. endtask
  160. /////////////////////////////////////// WRITE RESPONSE CHANNEL
  161. task driver::write_response_channel ();
  162. string s;
  163. packet write_response = packet::type_id::create("Response");
  164. write_response_sema.get(2);
  165. write_response_sema_1.get(1);
  166. @(vif.mas_dr);
  167. wait(vif.mas_dr.bvalid)
  168. write_response.bid = vif.mas_dr.bid;
  169. write_response.bresp = vif.mas_dr.bresp;
  170. vif.mas_dr.bready <= 1;
  171. @(vif.mas_dr);
  172. foreach (write_response_queue[i])
  173. begin
  174. if (write_response_queue[i].awid == write_response.bid)
  175. begin
  176. case (write_response.bresp)
  177. 2'b00 : s = "Transaction OKAY";
  178. 2'b01 : s = "Transaction FAILED";
  179. 2'b10 : s = "SLAVE ERROR";
  180. 2'b11 : s = "DEEOCDE ERROR";
  181. endcase
  182. `uvm_info("MASTER_DRIVER",$sformatf("\n\n \t\t\t\t\t\t %s RESPONSE FOR THE DATA \n",s),UVM_MEDIUM)
  183. write_response_queue[i].control = 1;
  184. `uvm_info("MASTER_DRIVER",$sformatf("\n %s \n",write_response_queue[i].sprint),UVM_MEDIUM);
  185. write_response_queue[i].control = 2;
  186. `uvm_info("MASTER_DRIVER",$sformatf("\n %s \n",write_response_queue[i].sprint),UVM_MEDIUM);
  187. write_response_queue.delete(i);
  188. break;
  189. end
  190. end
  191. vif.mas_dr.bready <= 0;
  192. @(vif.mas_dr);
  193. write_response_sema.put(1);
  194. write_response_sema_1.put(1);
  195. endtask
  196. /////////////////////////////////////// READ ADDRESS CHANNEL
  197. task driver::read_address_channel();
  198. read_address_sema.get(1);
  199. read_address = read_address_queue.pop_front();
  200. @(vif.mas_dr);
  201. read_address.control = 4;
  202. `uvm_info("MASTER_DRIVER",$sformatf("PRINTING FROM DRIVER \n %s",read_address.sprint()),UVM_HIGH)
  203. vif.mas_dr.arid <= read_address.arid;
  204. vif.mas_dr.araddr <= read_address.araddr;
  205. vif.mas_dr.arlen <= read_address.arlen;
  206. vif.mas_dr.arsize <= read_address.arsize;
  207. vif.mas_dr.arburst <= read_address.arburst;
  208. vif.mas_dr.arvalid <= 1;
  209. @(vif.mas_dr);
  210. wait (vif.mas_dr.arready);
  211. vif.mas_dr.arvalid <= 0;
  212. read_data_response_sema.put(1);
  213. read_address_sema.put(1);
  214. repeat(2)
  215. @(vif.mas_dr);
  216. endtask
  217. ////////////////////////////////////////// READ DATA AND RESPONSE CHANNEL
  218. task driver::read_data_response_channel();
  219. read_data_response_sema.get(2);
  220. read_data_response_sema_1.get(1);
  221. read_data = read_data_response_queue.pop_front();
  222. case (read_data.awburst)
  223. 2'b00 : rd_incr_burst;
  224. 2'b01 : rd_incr_burst;
  225. 2'b10 : rd_incr_burst;
  226. endcase
  227. read_data_response_sema_1.put(1);
  228. read_data_response_sema.put(1);
  229. endtask
  230. ////////////////////////////////////////// READ INCREMENT BURST
  231. task driver::rd_incr_burst();
  232. for (int i = 0;i < read_data.arlen+1; i++)
  233. begin
  234. wait(vif.mas_dr.rvalid);
  235. case (read_data.arsize)
  236. 2'b00 : read_data.rdata.push_back(vif.mas_dr.rdata[7:0]);
  237. 2'b01 : read_data.rdata.push_back(vif.mas_dr.rdata[15:0]);
  238. 2'b10 : read_data.rdata.push_back(vif.mas_dr.rdata[31:0]);
  239. endcase
  240. case(vif.mas_dr.rresp)
  241. 2'b00 : read_data.rresp[i] = "TRANSACTION OKAY \n";
  242. 2'b01 : read_data.rresp[i] = "TRANSACTION FAILED \n";
  243. 2'b10 : read_data.rresp[i] = "SLAVE ERROR \n";
  244. 2'b11 : read_data.rresp[i] = "DECODE ERROR \n";
  245. endcase
  246. repeat(read_data.rready_d)
  247. @(vif.mas_dr);
  248. vif.mas_dr.rready <= 1;
  249. @(vif.mas_dr);
  250. vif.mas_dr.rready <= 0;
  251. @(vif.mas_dr);
  252. end
  253. read_data.control = 5;
  254. `uvm_info("MASTER_DRIVER",$sformatf("PRINTING FROM DRIVER \n %s",read_data.sprint()),UVM_MEDIUM)
  255. endtask