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.

598 lines
12 KiB

  1. //driver
  2. class driver extends uvm_driver #(packet);
  3. `uvm_component_utils(driver)
  4. virtual axi_if vif;
  5. packet pkt;
  6. function new(string name="driver", uvm_component parent=null);
  7. super.new(name, parent);
  8. endfunction
  9. virtual function void build_phase(uvm_phase phase);
  10. super.build_phase(phase);
  11. pkt=packet::type_id::create("pkt");
  12. if(!uvm_config_db#(virtual axi_if)::get(this,"","vif",vif))
  13. `uvm_error("drv","Unable to access Interface");
  14. endfunction
  15. task reset_dut();
  16. repeat (3) begin
  17. //write address channel
  18. vif.awvalid <= 0;
  19. vif.awready <= 0;
  20. vif.awid <= 0;
  21. vif.awlen <= 0;
  22. vif.awsize <= 0;
  23. vif.awaddr <= 0;
  24. vif.awburst <= 0;
  25. //write data channel (w)
  26. vif.wvalid <= 0;
  27. vif.wready <= 0;
  28. vif.wid <= 0;
  29. vif.wdata <= 0;
  30. vif.wstrb <= 0;
  31. vif.wlast <= 0;
  32. //write response channel (b)
  33. vif.bready <= 0;
  34. vif.bvalid <= 0;
  35. vif.bid <= 0;
  36. vif.bresp <= 0;
  37. ///////////////read address channel (ar)
  38. vif.arvalid <= 0;
  39. vif.arready <= 0;
  40. vif.arid <= 0;
  41. vif.arlen <= 0;
  42. vif.arsize <= 0;
  43. vif.araddr <= 0;
  44. vif.arburst <= 0;
  45. /////////// read data channel (r)
  46. vif.rvalid <= 0;
  47. vif.rready <= 0;
  48. vif.rid <= 0;
  49. vif.rdata <= 0;
  50. vif.rstrb <= 0;
  51. vif.rlast <= 0;
  52. vif.rresp <= 0;
  53. //1 clk delay
  54. @(posedge vif.clk);
  55. `uvm_info(get_type_name(),"*** Reset Applied by driver ***",UVM_MEDIUM)
  56. end
  57. endtask
  58. virtual task run_phase(uvm_phase phase);
  59. reset_dut();
  60. forever begin
  61. seq_item_port.get_next_item(pkt);
  62. `uvm_info(get_type_name(),"*** Driver Received the transaction by sequencer ***",UVM_MEDIUM)
  63. //---------------------------------------------------------
  64. //----------------------------------------------------------
  65. //////////////////////////////////////// WRITE ADDRESS CHANNEL
  66. task write_address_pkt_channel();
  67. `uvm_info("MASTER_DRIVER",$sformatf("PRINTING FROM DRIVER \n %s",pkt.sprint()),UVM_HIGH)
  68. case (pkt.awburst)
  69. 2'b00 : write_address_fixed_burst;
  70. 2'b01 : write_address_incr_burst;
  71. 2'b10 : write_address_wrap_burst;
  72. endcase
  73. endtask
  74. //////////////////////////////////////// WRAP address BURST
  75. task write_address_wrap_burst();
  76. begin
  77. int start_addr=(`INT pkt.awaddr/((pkt.awlen+1)*(2**pkt.awsize)))*((pkt.awlen+1)*(2**pkt.awsize));
  78. int end_addr=(start_addr + ((pkt.awlen+1)*(2**pkt.awsize)));
  79. for (int i=0; i< (pkt.awlen+1);i++)
  80. begin
  81. vif.awaddr <= pkt.awaddr;
  82. if(vif.awaddr == end_addr)
  83. vif.awaddr <= start_addr;
  84. else
  85. vif.awaddr <= vif.awaddr+ (2**vif.awsize);
  86. vif.awid <= pkt.awid;
  87. vif.awvalid<= 1;
  88. wait(vif.awready);
  89. vif.awvalid<=0;
  90. end
  91. write_data_wrap_burst();
  92. endtask
  93. /////////////////////////////////////// wrapBURST
  94. task write_data_wrap_burst();
  95. if (vif.awvalid || vif.wvalid ||( vif.awvalid &&vif.wvalid))
  96. foreach(pkt.wdata[i])
  97. begin
  98. case (pkt.wstrobe[i])
  99. 4'b0001 : vif.wdata [7:0] <= pkt.wdata[i];
  100. 4'b0010 : vif.wdata [15:8] <= pkt.wdata[i];
  101. 4'b0100 : vif.wdata [23:16] <= pkt.wdata[i];
  102. 4'b1000 : vif.wdata [31:24] <= pkt.wdata[i];
  103. 4'b0011 : vif.wdata [15:0] <= pkt.wdata[i];
  104. 4'b1100 : vif.wdata [31:16] <= pkt.wdata[i];
  105. 4'b1110 : vif.wdata [31:8] <= pkt.wdata[i];
  106. 4'b1111 : vif.wdata [31:0] <= pkt.wdata[i];
  107. endcase
  108. vif.wstrobe <= pkt.wstrobe[i];
  109. vif.wid <= pkt.wid;
  110. if (i == pkt.awlen )
  111. vif.wlast <= 1;
  112. else
  113. vif.wlast <= 0;
  114. vif.wvalid <= 1;
  115. wait (vif.wready);
  116. vif.wlast <= 0;
  117. vif.wvalid <= 0;
  118. end
  119. write_response_channel ();
  120. endtask
  121. //////////////////////////////////////// INCR address INCREMENT BURST
  122. task write_address_incr_burst();
  123. vif.awlen <=pkt.awlen;
  124. for(int i=0; i<(awlen +1);i++)
  125. begin
  126. vif.awaddr<=pkt.awaddr;
  127. vif.awid <= pkt.awid;
  128. vif.awvalid<= 1;
  129. pkt.awaddr<= pkt.awaddr +(2**vif.awsize);
  130. wait(vif.awready);
  131. vif.awvalid<=0;
  132. end
  133. write_data_incr_burst();
  134. endtask
  135. /////////////////////////////////////// write data INCREMENT BURST
  136. task write_data_incr_burst();
  137. if (vif.awvalid || vif.wvalid ||( vif.awvalid &&vif.wvalid))
  138. foreach(pkt.wdata[i])
  139. begin
  140. case (pkt.wstrobe[i])
  141. 4'b0001 : vif.wdata [7:0] <= pkt.wdata[i];
  142. 4'b0010 : vif.wdata [15:8] <= pkt.wdata[i];
  143. 4'b0100 : vif.wdata [23:16] <= pkt.wdata[i];
  144. 4'b1000 : vif.wdata [31:24] <= pkt.wdata[i];
  145. 4'b0011 : vif.wdata [15:0] <= pkt.wdata[i];
  146. 4'b1100 : vif.wdata [31:16] <= pkt.wdata[i];
  147. 4'b1110 : vif.wdata [31:8] <= pkt.wdata[i];
  148. 4'b1111 : vif.wdata [31:0] <= pkt.wdata[i];
  149. endcase
  150. vif.wstrobe <= pkt.wstrobe[i];
  151. vif.wid <= pkt.wid;
  152. if (i == pkt.awlen )
  153. vif.wlast <= 1;
  154. else
  155. vif.wlast <= 0;
  156. vif.wvalid <= 1;
  157. wait (vif.wready);
  158. vif.wlast <= 0;
  159. vif.wvalid <= 0;
  160. end
  161. write_response_channel ();
  162. endtask
  163. ///////////////write address fixed burst
  164. task write_address_fixed_burst ();
  165. vif.awlen <= 4'b0000;
  166. vif.awid <= pkt.awid;
  167. vif.awaddr <= pkt.awaddr;
  168. vif.awvalid<= 1;
  169. wait(vif.awready);
  170. vif.awvalid<=0;
  171. write_data_fixed_burst();
  172. endtask
  173. ////////////////////////////////////// write data first burst
  174. task write_data_fixed_burst ();
  175. if (vif.awvalid || vif.wvalid ||( vif.awvalid &&vif.wvalid))
  176. foreach(pkt.wdata[i])
  177. begin
  178. case (pkt.awsize)
  179. 3'b000 : vif.wdata[7:0] <= pkt.wdata[i];
  180. 3'b001 : vif.wdata[15:0] <= pkt.wdata[i];
  181. 3'b010 : vif.wdata[31:0] <= pkt.wdata[i];
  182. 3'b011 : vif.wdata[63:0] <= pkt.wdata[i];
  183. 3'b100 : vif.wdata[127:0] <= pkt.wdata[i];
  184. 3'b101 : vif.wdata[255:0] <= pkt.wdata[i];
  185. 3'b110 : vif.wdata[511:0] <= pkt.wdata[i];
  186. 3'b110 : vif.wdata[1023:0] <= pkt.wdata[i];
  187. endcase
  188. vif.wid <= pkt.wid;
  189. if (i == pkt.awlen)
  190. vif.wlast <= 1;
  191. else
  192. vif.wlast <= 0;
  193. vif.wvalid <= 1;
  194. wait (vif.wready);
  195. vif.wlast <= 0;
  196. vif.wvalid <= 0;
  197. end
  198. write_response_channel ();
  199. endtask
  200. /////////////////////////////////////// WRITE RESPONSE CHANNEL
  201. task write_response_channel ();
  202. if (vif.awvalid && vif.awready && vif.awlast)
  203. wait(vif.bvalid)
  204. begin
  205. vif.bid = pkt.bid;
  206. vif.bresp = pkt.bresp;
  207. end
  208. vif.bready <= 1;
  209. foreach (vif.wdata[i])
  210. begin
  211. if (vif.awid == vif.bid)
  212. begin
  213. case (vif.bresp)
  214. 2'b00 : s = "Transaction OKAY";
  215. 2'b01 : s = "Transaction FAILED";
  216. 2'b10 : s = "SLAVE ERROR";
  217. 2'b11 : s = "DEEOCDE ERROR";
  218. endcase
  219. `uvm_info("MASTER_DRIVER",$sformatf("\n\n \t\t\t\t\t\t %s RESPONSE FOR THE DATA \n",s),UVM_MEDIUM)
  220. end
  221. end
  222. vif.bready <= 0;
  223. endtask
  224. /////////////////////////////////////// READ ADDRESS CHANNEL
  225. task read_address_pkt_channel();
  226. `uvm_info("MASTER_DRIVER",$sformatf("PRINTING FROM DRIVER \n %s",pkt.sprint()),UVM_HIGH)
  227. vif.arid <= pkt.arid;
  228. vif.araddr <= pkt.araddr;
  229. vif.arlen <= pkt.arlen;
  230. vif.arsize <= pkt.arsize;
  231. vif.arburst <= pkt.arburst;
  232. vif.arvalid <= 1;
  233. @(vif);
  234. wait (vif.arready);
  235. vif.arvalid <= 0;
  236. read_data_response_sema.put(1);
  237. pkt_sema.put(1);
  238. repeat(2)
  239. @(vif);
  240. endtask
  241. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  242. //////////////////////////////////////// WRITE ADDRESS CHANNEL
  243. task read_address_pkt_channel();
  244. `uvm_info("MASTER_DRIVER",$sformatf("PRINTING FROM DRIVER \n %s",pkt.sprint()),UVM_HIGH)
  245. case (pkt.awburst)
  246. 2'b00 : read_address_fixed_burst;
  247. 2'b01 : read_address_incr_burst;
  248. 2'b10 : read_address_wrap_burst;
  249. endcase
  250. endtask
  251. //////////////////////////////////////// WRAP address BURST
  252. task read_address_wrap_burst();
  253. begin
  254. int start_read_addr=(`INT pkt.araddr/((pkt.arlen+1)*(2**pkt.arsize)))*((pkt.arlen+1)*(2**pkt.arsize));
  255. int end_read_addr=(start_read_addr + ((pkt.arlen+1)*(2**pkt.arsize)));
  256. for (int i=0; i< (pkt.arlen+1);i++)
  257. begin
  258. vif.araddr <= pkt.araddr;
  259. if(vif.araddr == end_read_addr)
  260. vif.araddr <= start_read_addr;
  261. else
  262. vif.araddr <= vif.araddr+ (2**vif.arsize);
  263. vif.arid <= pkt.arid;
  264. vif.arvalid<= 1;
  265. wait(vif.arready);
  266. vif.arvalid<=0;
  267. end
  268. read_data_wrap_burst();
  269. endtask
  270. /////////////////////////////////////// wrapBURST
  271. task read_data_wrap_burst();
  272. if (vif.arvalid || vif.rvalid ||( vif.arvalid &&vif.rvalid))
  273. vif.arid <= pkt.rid;
  274. if (i == pkt.arlen )
  275. vif.rlast <= 1;
  276. else
  277. vif.rlast <= 0;
  278. vif.rvalid <= 1;
  279. wait (vif.rready);
  280. vif.rlast <= 0;
  281. vif.rvalid <= 0;
  282. end
  283. if (vif.arvalid && vif.arready && vif.arlast)
  284. wait(vif.rvalid)
  285. begin
  286. vif.rid = pkt.rid;
  287. vif.rresp = pkt.rresp;
  288. end
  289. vif.rready <= 1;
  290. foreach (vif.rdata[i])
  291. begin
  292. if (vif.arid == vif.rid)
  293. begin
  294. case (vif.rresp)
  295. 2'b00 : s = "Transaction OKAY";
  296. 2'b01 : s = "Transaction FAILED";
  297. 2'b10 : s = "SLAVE ERROR";
  298. 2'b11 : s = "DEEOCDE ERROR";
  299. endcase
  300. `uvm_info("MASTER_DRIVER",$sformatf("\n\n \t\t\t\t\t\t %s RESPONSE FOR THE DATA \n",s),UVM_MEDIUM)
  301. end
  302. end
  303. vif.rready <= 0;
  304. endtask
  305. //////////////////////////////////////// INCR address INCREMENT BURST
  306. task read_address_incr_burst();
  307. vif.arlen <=pkt.arlen;
  308. for(int i=0; i<(arlen +1);i++)
  309. begin
  310. vif.araddr<=pkt.araddr;
  311. vif.arid <= pkt.arid;
  312. vif.arvalid<= 1;
  313. pkt.araddr<= pkt.araddr +(2**vif.arsize);
  314. wait(vif.arready);
  315. vif.arvalid<=0;
  316. end
  317. read_data_incr_burst();
  318. endtask
  319. /////////////////////////////////////// read data INCREMENT BURST
  320. task read_data_incr_burst();
  321. if (vif.arvalid || vif.rvalid ||( vif.arvalid &&vif.rvalid))
  322. vif.rid <= pkt.rid;
  323. for(int i=0; i<(arlen +1);i++)
  324. begin
  325. vif.rdata <= pkt.rdata;
  326. if (i == pkt.arlen )
  327. vif.rlast <= 1;
  328. else
  329. vif.rlast <= 0;
  330. vif.rvalid <= 1;
  331. wait (vif.rready);
  332. vif.rlast <= 0;
  333. vif.rvalid <= 0;
  334. end
  335. if (vif.arvalid && vif.arready && vif.arlast)
  336. wait(vif.rvalid)
  337. begin
  338. vif.rid = pkt.rid;
  339. vif.rresp = pkt.rresp;
  340. end
  341. vif.rready <= 1;
  342. foreach (vif.rdata[i])
  343. begin
  344. if (vif.arid == vif.rid)
  345. begin
  346. case (vif.rresp)
  347. 2'b00 : s = "Transaction OKAY";
  348. 2'b01 : s = "Transaction FAILED";
  349. 2'b10 : s = "SLAVE ERROR";
  350. 2'b11 : s = "DEEOCDE ERROR";
  351. endcase
  352. `uvm_info("MASTER_DRIVER",$sformatf("\n\n \t\t\t\t\t\t %s RESPONSE FOR THE DATA \n",s),UVM_MEDIUM)
  353. end
  354. end
  355. vif.rready <= 0;
  356. endtask
  357. ///////////////read address fixed burst
  358. task read_address_fixed_burst ();
  359. begin
  360. vif.arlen <= 4'b0000;
  361. vif.arid <= pkt.arid;
  362. vif.araddr <= pkt.araddr;
  363. vif.arvalid<= 1;
  364. wait(vif.arready);
  365. vif.arvalid<=0;
  366. end
  367. read_data_fixed_burst();
  368. endtask
  369. ////////////////////////////////////// read data first burst
  370. task read_data_fixed_burst ();
  371. if (vif.arvalid || vif.rvalid ||( vif.arvalid &&vif.rvalid))
  372. foreach(pkt.rdata[i])
  373. begin
  374. case (pkt.arsize)
  375. 3'b000 : vif.rdata[7:0] <= pkt.rdata[i];
  376. 3'b001 : vif.rdata[15:0] <= pkt.rdata[i];
  377. 3'b010 : vif.rdata[31:0] <= pkt.rdata[i];
  378. 3'b011 : vif.rdata[63:0] <= pkt.rdata[i];
  379. 3'b100 : vif.rdata[127:0] <= pkt.rdata[i];
  380. 3'b101 : vif.rdata[255:0] <= pkt.rdata[i];
  381. 3'b110 : vif.rdata[511:0] <= pkt.rdata[i];
  382. 3'b110 : vif.rdata[1023:0] <= pkt.rdata[i];
  383. endcase
  384. vif.rid <= pkt.rid;
  385. if (i == pkt.arlen)
  386. vif.rlast <= 1;
  387. else
  388. vif.rlast <= 0;
  389. vif.rvalid <= 1;
  390. wait (vif.rready);
  391. vif.rlast <= 0;
  392. vif.rvalid <= 0;
  393. end
  394. if (vif.arvalid && vif.arready && vif.arlast)
  395. wait(vif.rvalid)
  396. begin
  397. vif.rid = pkt.rid;
  398. vif.rresp = pkt.rresp;
  399. end
  400. vif.rready <= 1;
  401. foreach (vif.rdata[i])
  402. begin
  403. if (vif.arid == vif.rid)
  404. begin
  405. case (vif.rresp)
  406. 2'b00 : s = "Transaction OKAY";
  407. 2'b01 : s = "Transaction FAILED";
  408. 2'b10 : s = "SLAVE ERROR";
  409. 2'b11 : s = "DEEOCDE ERROR";
  410. endcase
  411. `uvm_info("MASTER_DRIVER",$sformatf("\n\n \t\t\t\t\t\t %s RESPONSE FOR THE DATA \n",s),UVM_MEDIUM)
  412. end
  413. end
  414. vif.rready <= 0;
  415. endtask
  416. //--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  417. if(pkt.op==RESET) begin
  418. reset_dut();
  419. end
  420. //Write operation support
  421. else if(pkt.op == WRITE) begin
  422. `uvm_info(get_type_name(),"*** WRITE packet is received in driver ***",UVM_MEDIUM)
  423. begin
  424. write_address_pkt_channel();
  425. end
  426. //read operation support
  427. else if( pkt.op == READ)
  428. begin
  429. read_address_pkt_channel();
  430. //put read drive logic here
  431. end
  432. seq_item_port.item_done();
  433. end
  434. endtask
  435. endclass