AXI-Verification architecture, functional coverage and assertions based coverage code
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

394 lignes
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.driver);
  76. req.control = 1;
  77. `uvm_info("MASTER_DRIVER",$sformatf("PRINTING FROM DRIVER \n %s",write_address.sprint()),UVM_HIGH)
  78. vif.driver.awid <= write_address.awid;
  79. vif.driver.awaddr <= write_address.awaddr;
  80. vif.driver.awlen <= write_address.awlen;
  81. vif.driver.awsize <= write_address.awsize;
  82. vif.driver.awburst <= write_address.awburst;
  83. vif.driver.awvalid <= 1;
  84. @(vif.driver);
  85. wait (vif.driver.awready);
  86. vif.driver.awvalid <= 0;
  87. write_data_sema.put(1);
  88. write_address_sema.put(1);
  89. repeat(2)
  90. @(vif.driver);
  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.driver);
  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.driver.wdata [7:0] <= write_data.wdata[i];
  116. 4'b0010 : vif.driver.wdata [15:8] <= write_data.wdata[i];
  117. 4'b0100 : vif.driver.wdata [23:16] <= write_data.wdata[i];
  118. 4'b1000 : vif.driver.wdata [31:24] <= write_data.wdata[i];
  119. 4'b0011 : vif.driver.wdata [15:0] <= write_data.wdata[i];
  120. 4'b1100 : vif.driver.wdata [31:16] <= write_data.wdata[i];
  121. 4'b1110 : vif.driver.wdata [31:8] <= write_data.wdata[i];
  122. 4'b1111 : vif.driver.wdata <= write_data.wdata[i];
  123. endcase
  124. vif.driver.wstrobe <= write_data.wstrobe[i];
  125. vif.driver.wid <= write_data.wid;
  126. if (i == write_data.burst_len - 1)
  127. vif.driver.wlast <= 1;
  128. else
  129. vif.driver.wlast <= 0;
  130. vif.driver.wvalid <= 1;
  131. @(vif.driver);
  132. wait (vif.driver.wready);
  133. vif.driver.wlast <= 0;
  134. vif.driver.wvalid <= 0;
  135. @(vif.driver);
  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.driver.wdata[7:0] <= write_data.wdata[i];
  144. 2'b01 : vif.driver.wdata[15:0] <= write_data.wdata[i];
  145. 2'b10 : vif.driver.wdata[31:0] <= write_data.wdata[i];
  146. endcase
  147. vif.driver.wid <= write_data.wid;
  148. if (i == write_data.burst_len - 1)
  149. vif.driver.wlast <= 1;
  150. else
  151. vif.driver.wlast <= 0;
  152. vif.driver.wvalid <= 1;
  153. @(vif.driver);
  154. wait (vif.driver.wready);
  155. vif.driver.wlast <= 0;
  156. vif.driver.wvalid <= 0;
  157. @(vif.driver);
  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.driver);
  167. wait(vif.driver.bvalid)
  168. write_response.bid = vif.driver.bid;
  169. write_response.bresp = vif.driver.bresp;
  170. vif.driver.bready <= 1;
  171. @(vif.driver);
  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.driver.bready <= 0;
  192. @(vif.driver);
  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.driver);
  201. read_address.control = 4;
  202. `uvm_info("MASTER_DRIVER",$sformatf("PRINTING FROM DRIVER \n %s",read_address.sprint()),UVM_HIGH)
  203. vif.driver.arid <= read_address.arid;
  204. vif.driver.araddr <= read_address.araddr;
  205. vif.driver.arlen <= read_address.arlen;
  206. vif.driver.arsize <= read_address.arsize;
  207. vif.driver.arburst <= read_address.arburst;
  208. vif.driver.arvalid <= 1;
  209. @(vif.driver);
  210. wait (vif.driver.arready);
  211. vif.driver.arvalid <= 0;
  212. read_data_response_sema.put(1);
  213. read_address_sema.put(1);
  214. repeat(2)
  215. @(vif.driver);
  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.driver.rvalid);
  235. case (read_data.arsize)
  236. 2'b00 : read_data.rdata.push_back(vif.driver.rdata[7:0]);
  237. 2'b01 : read_data.rdata.push_back(vif.driver.rdata[15:0]);
  238. 2'b10 : read_data.rdata.push_back(vif.driver.rdata[31:0]);
  239. endcase
  240. case(vif.driver.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.driver);
  248. vif.driver.rready <= 1;
  249. @(vif.driver);
  250. vif.driver.rready <= 0;
  251. @(vif.driver);
  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