您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

axi_driver.sv 11 KiB

6 个月前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. class driver extends uvm_driver #(seq);
  2. `uvm_component_utils(driver)
  3. virtual axi_driver_if vif;
  4. sequence seq;
  5. function new(string name="driver", uvm_component parent=null);
  6. super.new(name, parent);
  7. endfunction
  8. virtual function void build_phase(uvm_phase phase);
  9. super.build_phase(phase);
  10. seq=sequence::type_id::create("seq");
  11. if(!uvm_config_db#(virtual axi_driver_if)::get(this," ","vif",vif))
  12. `uvm_error("driver"," Interface not set");
  13. endfunction
  14. task reset();
  15. begin
  16. vif.awvalid <= 0;
  17. vif.awready <= 0;
  18. vif.awid <= 0;
  19. vif.awlen <= 0;
  20. vif.awsize <= 0;
  21. vif.awaddr <= 0;
  22. vif.awburst <= 0;
  23. vif.wvalid <= 0;
  24. vif.wready <= 0;
  25. vif.wid <= 0;
  26. vif.wdata <= 0;
  27. vif.wstrb <= 0;
  28. vif.wlast <= 0;
  29. vif.bready <= 0;
  30. vif.bvalid <= 0;
  31. vif.bid <= 0;
  32. vif.bresp <= 0;
  33. vif.arvalid <= 0;
  34. vif.arready <= 0;
  35. vif.arid <= 0;
  36. vif.arlen <= 0;
  37. vif.arsize <= 0;
  38. vif.araddr <= 0;
  39. vif.arburst <= 0;
  40. vif.rvalid <= 0;
  41. vif.rready <= 0;
  42. vif.rid <= 0;
  43. vif.rdata <= 0;
  44. vif.rstrb <= 0;
  45. vif.rlast <= 0;
  46. vif.rresp <= 0;
  47. @(posedge vif.clk);
  48. `uvm_info(get_type_name(),"reset applied",UVM_MEDIUM)
  49. end
  50. endtask
  51. virtual task run_phase(uvm_phase phase);
  52. reset();
  53. seq_tem_port.get_next_item(txn);
  54. if(wr_rd==1)
  55. begin
  56. wrtie_address();
  57. write_data();
  58. write_response();
  59. end
  60. else
  61. begin
  62. read_address();
  63. read_data();
  64. end
  65. endtask
  66. virtual task write_address();
  67. vif.awready<=0;
  68. vif.awaddr<= txn.awaddr;
  69. vif.awsize<= txn.awsize;
  70. vif.awlen<= txn.awlen;
  71. vif.awcache<= txn.awcache;
  72. vif.awburst<= txn.awburst;
  73. vif.awvalid<=1'b1;
  74. case (txn.awburst)
  75. 2'b00 : write_ad_fixed_burst;
  76. 2'b01 : write_ad_incr_burst;
  77. 2'b10 : write_ad_wrap_burst;
  78. endcase
  79. while(vif.awready==0)
  80. $display("within loop");
  81. begin
  82. @(posedge vif.clk);
  83. if(vif.awvalid==1)
  84. begin
  85. awready=1;
  86. $display("write address phase is completed");
  87. end
  88. end
  89. vif.awvalid=0;
  90. endtask
  91. ////////////////// wridte_fixed burst////////////////
  92. virtual task write_ad_fixed_burst();
  93. vif.awlen <= txn.awlen;
  94. vif.awid <= txn.awid;
  95. vif.awaddr <= txn.awaddr;
  96. vif.awsize<= txn.awsize;
  97. vif.awvalid<= 1;
  98. wait(vif.awready);
  99. vif.awvalid<=0;
  100. write_data();
  101. endtask
  102. virtual task write_data();
  103. vif.wready<=0;
  104. for(int i=0;i<=txn.awlen+1;i++) begin
  105. $display("write data started");
  106. vif.wdata<=txn.wdata[i];
  107. vif.wstrb<=txn.wstrb[i];
  108. vif.wid<=txn.wid;
  109. vif.wvalid<=1'b1;
  110. if(i=txn.awlen+1) vif.wlast=1;
  111. while (wready=0)
  112. begin @(posedge vif.clk)
  113. if (vif.wready==1)
  114. txn.wready=1;
  115. end
  116. vif.wlast=0;
  117. vif.wvalid=0;
  118. vif.wready=0;
  119. $display("write data completed");
  120. end
  121. write_ad_incr();
  122. endtask
  123. //////////////////////write_address_incremental/////////////////
  124. virtual task write_ad_incr();
  125. vif.awlen <= txn.awlen;
  126. for(int i=0; i<(txn.awlen +1);i++)
  127. vif.awid <= txn.awid;
  128. vif.awaddr <= txn.awaddr;
  129. vif.awsize<= txn.awsize;
  130. txn.awaddr<= txn.awaddr+(2**awsize);
  131. vif.awvalid<= 1;
  132. wait(vif.awready);
  133. vif.awvalid<=0;
  134. write_data();
  135. endtask
  136. virtual task write_data();
  137. vif.wready<=0;
  138. for(int i=0;i<=txn.awlen+1;i++) begin
  139. $display("write data started");
  140. vif.wdata<=txn.wdata[i];
  141. vif.wstrb<=txn.wstrb[i];
  142. vif.wid<=txn.wid;
  143. vif.wvalid<=1'b1;
  144. if(i=txn.awlen+1) vif.wlast=1;
  145. while (wready=0)
  146. begin @(posedge vif.clk)
  147. if (vif.wready==1)
  148. txn.wready=1;
  149. end
  150. vif.wlast=0;
  151. vif.wvalid=0;
  152. vif.wready=0;
  153. $display("write data completed");
  154. write_ad_wrap();
  155. end
  156. endtask
  157. ///////////wri_address_wrap///////////////////////
  158. virtual task write_ad_wrap();
  159. vif.awlen <= '{1,3,7,15};
  160. vif.awid <= txn.awid;
  161. vif.awaddr <= txn.awaddr;
  162. vif.awsize<= txn.awsize;
  163. begin
  164. int burst_length=(awlen+1);
  165. int burst_size=(awsize+1);
  166. int lower_boundary=INT[awaddr/(burst_length*burst_size)]*(burst_length*burst_size);
  167. int upper_boundary=lower_boundar+(burst_length*burst_size);
  168. for (int i=0; i< (pkt.awlen+1);i++)
  169. begin
  170. if(vif.awaddr==upper_boundary)
  171. vif.awaddr=lower_boundary;
  172. else
  173. vif.awaddr <= vif.awaddr+ (2**vif.awsize);
  174. vif.awvalid<= 1;
  175. wait(vif.awready);
  176. vif.awvalid<=0;
  177. end
  178. write_data();
  179. endtask
  180. virtual task write_data();
  181. vif.wready<=0;
  182. for(int i=0;i<=txn.awlen+1;i++) begin
  183. $display("write data started");
  184. vif.wdata<=txn.wdata[i];
  185. vif.wstrb<=txn.wstrb[i];
  186. vif.wid<=txn.wid;
  187. vif.wvalid<=1'b1;
  188. if(i=txn.awlen+1) vif.wlast=1;
  189. while (wready=0)
  190. begin @(posedge vif.clk)
  191. if (vif.wready==1)
  192. txn.wready=1;
  193. end
  194. vif.wlast=0;
  195. vif.wvalid=0;
  196. vif.wready=0;
  197. $display("write data completed");
  198. write_response();
  199. end
  200. endtask
  201. virtual task write_response();
  202. if(vif.wvalid&&vif.wready&&vif.wlast)
  203. wait(bvalid)
  204. begin
  205. vif.bid = pkt.bid;
  206. vif.bresp = pkt.bresp;
  207. end
  208. vif.bready <= 1 ;
  209. for(i=0;i<=awlen+1;i++)
  210. begin
  211. if(vif.awid==vif.bid)
  212. case(vif.bresp)
  213. 2'b00:"okay";
  214. 2'b01:"exclusive okay";
  215. 2'b10:"slave error";
  216. 2'b11:"decode error";
  217. endcase
  218. end
  219. vif.bready<=0;
  220. endtask
  221. ///////////////////////Read address////////////////////////////////////////////////
  222. task read_adress();
  223. `uvm_info("master_driver",$sformatf("message from driver\n %s",pkt.sprint()),UVM_HIGH)
  224. vif.arid <= pkt.arid;
  225. vif.araddr <= pkt.araddr;
  226. vif.arlen <= pkt.arlen;
  227. vif.arsize <= pkt.arsize;
  228. vif.arburst <= pkt.arburst;
  229. vif.arvalid <= 1;
  230. `uvm_info("master_driver",$sformatf("message from driver \n %s",pkt.sprint()),UVM_HIGH)
  231. case (txn.arburst)
  232. 2'b00 : read_address_fixed_burst;
  233. 2'b01 : read_address_incr_burst;
  234. 2'b10 : read_address_wrap_burst;
  235. endcase
  236. @(posedge vif.clk);
  237. wait (vif.arready);
  238. vif.arvalid <= 0;
  239. endtask
  240. //////////////////////////////////////// raed wrap burst////////////////////
  241. virtual task read_ad_wrap();
  242. vif.awlen <= '{1,3,7,15};
  243. vif.arid <= txn.arid;
  244. vif.araddr <= txn.araddr;
  245. vif.arsize<= txn.arsize;
  246. begin
  247. int burst_length=(arlen+1);
  248. int burst_size=(arsize+1);
  249. int lower_boundary=INT[araddr/(burst_length*burst_size)]*(burst_length*burst_size);
  250. int upper_boundary=lower_boundar+(burst_length*burst_size);
  251. for (int i=0; i< (pkt.arlen+1);i++)
  252. begin
  253. if(vif.araddr==upper_boundary)
  254. vif.araddr=lower_boundary;
  255. else
  256. vif.araddr <= vif.araddr+ (2**vif.arsize);
  257. vif.arvalid<= 1;
  258. wait(vif.arready);
  259. vif.arvalid<=0;
  260. end
  261. read_data1();
  262. endtask
  263. virtual task read_data1();
  264. vif.rready<=0;
  265. for(int i=0;i<=txn.arlen+1;i++) begin
  266. $display("read data started");
  267. vif.rdata<=txn.rdata[i];
  268. vif.rid<=txn.rid;
  269. vif.rvalid<=1'b1;
  270. if(i=txn.arlen+1) vif.rlast=1;
  271. while (rready=0)
  272. begin @(posedge vif.clk)
  273. if (vif.rready==1)
  274. txn.rready=1;
  275. end
  276. vif.rlast=0;
  277. vif.rvalid=0;
  278. $display("read data completed");
  279. end
  280. foreach (vif.rdata[i])
  281. begin
  282. if (vif.arid == vif.rid)
  283. begin
  284. case (vif.rresp)
  285. 2'b00 : s = "Transaction OKAY";
  286. 2'b01 : s = "Transaction FAILED";
  287. 2'b10 : s = "SLAVE ERROR";
  288. 2'b11 : s = "DEEOCDE ERROR";
  289. endcase
  290. `uvm_info("axi master_driver",$sformatf("\n t %s response for the received data \n",s),UVM_MEDIUM)
  291. end
  292. end
  293. vif.rready <= 0;
  294. endtask
  295. //////////////////////////////////////// INCR address ////////////////
  296. task read_address_incr_burst();
  297. vif.arlen <=txn.arlen;
  298. for(int i=0; i<(arlen +1);i++)
  299. begin
  300. vif.araddr<=txn.araddr;
  301. vif.arid <= txn.arid;
  302. vif.arvalid<= 1;
  303. pkt.araddr<= txn.araddr +(2**vif.arsize);
  304. wait(vif.arready);
  305. vif.arvalid<=0;
  306. end
  307. read_data();
  308. endtask
  309. virtual task read_data();
  310. vif.rready<=0;
  311. for(int i=0;i<=txn.arlen+1;i++) begin
  312. $display("read data started");
  313. vif.rdata<=txn.rdata[i];
  314. vif.rid<=txn.rid;
  315. vif.rvalid<=1'b1;
  316. if(i=txn.arlen+1) vif.rlast=1;
  317. while (rready=0)
  318. begin @(posedge vif.clk)
  319. if (vif.rready==1)
  320. txn.rready=1;
  321. end
  322. vif.rlast=0;
  323. vif.rvalid=0;
  324. $display("read data completed");
  325. end
  326. vif.rready <= 1;
  327. foreach (vif.rdata[i])
  328. begin
  329. if (vif.arid == vif.rid)
  330. begin
  331. case (vif.rresp)
  332. 2'b00 : s = "Transaction OKAY";
  333. 2'b01 : s = "Transaction FAILED";
  334. 2'b10 : s = "SLAVE ERROR";
  335. 2'b11 : s = "DEEOCDE ERROR";
  336. endcase
  337. `uvm_info("master_driver",$sformatf("\n\t %s response for the recieved data \n",s),UVM_MEDIUM)
  338. end
  339. end
  340. vif.rready <= 0;
  341. endtask
  342. ///////////////read address fixed burst////////////////////////
  343. task read_address_fixed_burst ();
  344. begin
  345. vif.arlen <= txn.arlen;
  346. vif.arid <= txn.arid;
  347. vif.araddr <= txn.araddr;
  348. vif.arvalid<= 1;
  349. wait(vif.arready);
  350. vif.arvalid<=0;
  351. end
  352. rd_dt_fixed_burst();
  353. endtask
  354. task rd_dt_fixed_burst ();
  355. vif.rready<=0;
  356. for(int i=0;i<=txn.arlen+1;i++) begin
  357. $display("read data started");
  358. vif.rdata<=txn.rdata[i];
  359. vif.rid<=txn.rid;
  360. vif.rvalid<=1'b1;
  361. if(i=txn.arlen+1) vif.rlast=1;
  362. while (rready=0)
  363. begin @(posedge vif.clk)
  364. if (vif.rready==1)
  365. txn.rready=1;
  366. end
  367. vif.rlast=0;
  368. vif.rvalid=0;
  369. $display("read data completed");
  370. end
  371. foreach (vif.rdata[i])
  372. begin
  373. if (vif.arid == vif.rid)
  374. begin
  375. case (vif.rresp)
  376. 2'b00 : s = "Transaction OKAY";
  377. 2'b01 : s = "Transaction FAILED";
  378. 2'b10 : s = "SLAVE ERROR";
  379. 2'b11 : s = "DEEOCDE ERROR";
  380. endcase
  381. `uvm_info("master_driver",$sformatf("\n\t %s response for recieved data \n",s),UVM_MEDIUM)
  382. end
  383. end
  384. vif.rready <= 0;
  385. endtask
  386. if(txn.resest==1) begin
  387. reset();
  388. end
  389. //Write operation support
  390. else if(txn.wr_rd==1) begin
  391. `uvm_info(get_type_name()," write packet is received in driver ",UVM_MEDIUM)
  392. begin
  393. write_address();
  394. end
  395. //read operation support
  396. else if( txn.wr_rd==0)
  397. begin
  398. read_address();
  399. end
  400. seq_item_port.item_done();
  401. end
  402. endtask
  403. endclass