25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 

708 satır
17 KiB

  1. `timescale 1ns / 1ps
  2. /*
  3. module tb();
  4. reg presetn = 0;
  5. reg pclk = 0;
  6. reg psel = 0;
  7. reg penable = 0 ;
  8. reg pwrite = 0;
  9. reg [31:0] paddr = 0, pwdata = 0;
  10. wire [31:0] prdata;
  11. wire pready, pslverr;
  12. apb_ram dut (presetn, pclk, psel, penable, pwrite, paddr, pwdata, prdata, pready, pslverr);
  13. always #10 pclk = ~pclk;
  14. initial begin
  15. presetn = 0;
  16. repeat(5) @(posedge pclk);
  17. presetn = 1;
  18. psel = 1;
  19. pwrite = 1;
  20. paddr = 12;
  21. pwdata = 35;
  22. @(posedge pclk);
  23. penable = 1;
  24. @(posedge pready);
  25. psel = 0;
  26. penable = 0;
  27. @(posedge pclk);
  28. psel = 1;
  29. pwrite = 1'b0;
  30. paddr = 12;
  31. pwdata = 35;
  32. @(posedge pclk);
  33. penable = 1'b1;
  34. @(posedge pready);
  35. psel = 0;
  36. penable = 0;
  37. @(posedge pclk);
  38. psel = 1;
  39. pwrite = 1;
  40. paddr = 45;
  41. pwdata = 35;
  42. @(posedge pclk);
  43. penable = 1;
  44. @(posedge pready);
  45. psel = 0;
  46. penable = 0;
  47. @(posedge pclk);
  48. psel = 1;
  49. pwrite = 0;
  50. paddr = 45;
  51. pwdata = 35;
  52. @(posedge pclk);
  53. penable = 1;
  54. @(posedge pready);
  55. @(posedge pclk);
  56. $stop();
  57. end
  58. endmodule
  59. */
  60. `include "uvm_macros.svh"
  61. import uvm_pkg::*;
  62. ////////////////////////////////////////////////////////////////////////////////////
  63. class abp_config extends uvm_object; /////configuration of env
  64. `uvm_object_utils(abp_config)
  65. function new(string name = "abp_config");
  66. super.new(name);
  67. endfunction
  68. uvm_active_passive_enum is_active = UVM_ACTIVE;
  69. endclass
  70. ///////////////////////////////////////////////////////
  71. typedef enum bit [1:0] {readd = 0, writed = 1, rst = 2} oper_mode;
  72. //////////////////////////////////////////////////////////////////////////////////
  73. class transaction extends uvm_sequence_item;
  74. rand oper_mode op;
  75. rand logic PWRITE;
  76. rand logic [31 : 0] PWDATA;
  77. rand logic [31 : 0] PADDR;
  78. // Output Signals of DUT for APB UART's transaction
  79. logic PREADY;
  80. logic PSLVERR;
  81. logic [31: 0] PRDATA;
  82. `uvm_object_utils_begin(transaction)
  83. `uvm_field_int (PWRITE,UVM_ALL_ON)
  84. `uvm_field_int (PWDATA,UVM_ALL_ON)
  85. `uvm_field_int (PADDR,UVM_ALL_ON)
  86. `uvm_field_int (PREADY,UVM_ALL_ON)
  87. `uvm_field_int (PSLVERR,UVM_ALL_ON)
  88. `uvm_field_int (PRDATA,UVM_ALL_ON)
  89. `uvm_field_enum(oper_mode, op, UVM_DEFAULT)
  90. `uvm_object_utils_end
  91. constraint addr_c { PADDR <= 31; }
  92. constraint addr_c_err { PADDR > 31; }
  93. function new(string name = "transaction");
  94. super.new(name);
  95. endfunction
  96. endclass : transaction
  97. ///////////////////////////////////////////////////////////////
  98. /*
  99. module tb;
  100. transaction tr;
  101. initial begin
  102. tr = transaction::type_id::create("tr");
  103. tr.randomize();
  104. tr.print();
  105. end
  106. endmodule
  107. */
  108. //////////////////////////////////////////////////////////////////
  109. ///////////////////write seq
  110. class write_data extends uvm_sequence#(transaction);
  111. `uvm_object_utils(write_data)
  112. transaction tr;
  113. function new(string name = "write_data");
  114. super.new(name);
  115. endfunction
  116. virtual task body();
  117. repeat(15)
  118. begin
  119. tr = transaction::type_id::create("tr");
  120. tr.addr_c.constraint_mode(1);//enable
  121. tr.addr_c_err.constraint_mode(0);//disable
  122. start_item(tr);
  123. assert(tr.randomize);
  124. tr.op = writed;
  125. finish_item(tr);
  126. end
  127. endtask
  128. endclass
  129. //////////////////////////////////////////////////////////
  130. ////////////////////////read seq
  131. class read_data extends uvm_sequence#(transaction);
  132. `uvm_object_utils(read_data)
  133. transaction tr;
  134. function new(string name = "read_data");
  135. super.new(name);
  136. endfunction
  137. virtual task body();
  138. repeat(15)
  139. begin
  140. tr = transaction::type_id::create("tr");
  141. tr.addr_c.constraint_mode(1);
  142. tr.addr_c_err.constraint_mode(0);//disable
  143. start_item(tr);
  144. assert(tr.randomize);
  145. tr.op = readd;
  146. finish_item(tr);
  147. end
  148. endtask
  149. endclass
  150. /////////////////////////////////////////////
  151. class write_read extends uvm_sequence#(transaction); //////read after write
  152. `uvm_object_utils(write_read)
  153. transaction tr;
  154. function new(string name = "write_read");
  155. super.new(name);
  156. endfunction
  157. virtual task body();
  158. repeat(15)
  159. begin
  160. tr = transaction::type_id::create("tr");
  161. tr.addr_c.constraint_mode(1);
  162. tr.addr_c_err.constraint_mode(0);
  163. start_item(tr);
  164. assert(tr.randomize);
  165. tr.op = writed;
  166. finish_item(tr);
  167. start_item(tr);
  168. assert(tr.randomize);
  169. tr.op = readd;
  170. finish_item(tr);
  171. end
  172. endtask
  173. endclass
  174. ///////////////////////////////////////////////////////
  175. ///////////////write bulk read bulk
  176. class writeb_readb extends uvm_sequence#(transaction);
  177. `uvm_object_utils(writeb_readb)
  178. transaction tr;
  179. function new(string name = "writeb_readb");
  180. super.new(name);
  181. endfunction
  182. virtual task body();
  183. repeat(15) begin
  184. tr = transaction::type_id::create("tr");
  185. tr.addr_c.constraint_mode(1);
  186. tr.addr_c_err.constraint_mode(0);
  187. start_item(tr);
  188. assert(tr.randomize);
  189. tr.op = writed;
  190. finish_item(tr);
  191. end
  192. repeat(15) begin
  193. tr = transaction::type_id::create("tr");
  194. tr.addr_c.constraint_mode(1);
  195. tr.addr_c_err.constraint_mode(0);
  196. start_item(tr);
  197. assert(tr.randomize);
  198. tr.op = readd;
  199. finish_item(tr);
  200. end
  201. endtask
  202. endclass
  203. /////////////////////////////////////////////////////////////////
  204. //////////////////////slv_error_write
  205. class write_err extends uvm_sequence#(transaction);
  206. `uvm_object_utils(write_err)
  207. transaction tr;
  208. function new(string name = "write_err");
  209. super.new(name);
  210. endfunction
  211. virtual task body();
  212. repeat(15)
  213. begin
  214. tr = transaction::type_id::create("tr");
  215. tr.addr_c.constraint_mode(0);
  216. tr.addr_c_err.constraint_mode(1);
  217. start_item(tr);
  218. assert(tr.randomize);
  219. tr.op = writed;
  220. finish_item(tr);
  221. end
  222. endtask
  223. endclass
  224. ///////////////////////////////////////////////////////////////
  225. /////////////////////////read err
  226. class read_err extends uvm_sequence#(transaction);
  227. `uvm_object_utils(read_err)
  228. transaction tr;
  229. function new(string name = "read_err");
  230. super.new(name);
  231. endfunction
  232. virtual task body();
  233. repeat(15)
  234. begin
  235. tr = transaction::type_id::create("tr");
  236. tr.addr_c.constraint_mode(0);
  237. tr.addr_c_err.constraint_mode(1);
  238. start_item(tr);
  239. assert(tr.randomize);
  240. tr.op = readd;
  241. finish_item(tr);
  242. end
  243. endtask
  244. endclass
  245. ///////////////////////////////////////////////////////////////
  246. class reset_dut extends uvm_sequence#(transaction);
  247. `uvm_object_utils(reset_dut)
  248. transaction tr;
  249. function new(string name = "reset_dut");
  250. super.new(name);
  251. endfunction
  252. virtual task body();
  253. repeat(15)
  254. begin
  255. tr = transaction::type_id::create("tr");
  256. tr.addr_c.constraint_mode(1);
  257. tr.addr_c_err.constraint_mode(0);
  258. start_item(tr);
  259. assert(tr.randomize);
  260. tr.op = rst;
  261. finish_item(tr);
  262. end
  263. endtask
  264. endclass
  265. ////////////////////////////////////////////////////////////
  266. class driver extends uvm_driver #(transaction);
  267. `uvm_component_utils(driver)
  268. virtual apb_if vif;
  269. transaction tr;
  270. function new(input string path = "drv", uvm_component parent = null);
  271. super.new(path,parent);
  272. endfunction
  273. virtual function void build_phase(uvm_phase phase);
  274. super.build_phase(phase);
  275. tr = transaction::type_id::create("tr");
  276. if(!uvm_config_db#(virtual apb_if)::get(this,"","vif",vif))//uvm_test_top.env.agent.drv.aif
  277. `uvm_error("drv","Unable to access Interface");
  278. endfunction
  279. task reset_dut();
  280. repeat(5)
  281. begin
  282. vif.presetn <= 1'b0;
  283. vif.paddr <= 'h0;
  284. vif.pwdata <= 'h0;
  285. vif.pwrite <= 'b0;
  286. vif.psel <= 'b0;
  287. vif.penable <= 'b0;
  288. `uvm_info("DRV", "System Reset : Start of Simulation", UVM_MEDIUM);
  289. @(posedge vif.pclk);
  290. end
  291. endtask
  292. task drive();
  293. reset_dut();
  294. forever begin
  295. seq_item_port.get_next_item(tr);
  296. if(tr.op == rst)
  297. begin
  298. vif.presetn <= 1'b0;
  299. vif.paddr <= 'h0;
  300. vif.pwdata <= 'h0;
  301. vif.pwrite <= 'b0;
  302. vif.psel <= 'b0;
  303. vif.penable <= 'b0;
  304. @(posedge vif.pclk);
  305. end
  306. else if(tr.op == writed)
  307. begin
  308. vif.psel <= 1'b1;
  309. vif.paddr <= tr.PADDR;
  310. vif.pwdata <= tr.PWDATA;
  311. vif.presetn <= 1'b1;
  312. vif.pwrite <= 1'b1;
  313. @(posedge vif.pclk);
  314. vif.penable <= 1'b1;
  315. `uvm_info("DRV", $sformatf("mode:%0s, addr:%0d, wdata:%0d, rdata:%0d, slverr:%0d",tr.op.name(),tr.PADDR,tr.PWDATA,tr.PRDATA,tr.PSLVERR), UVM_NONE);
  316. @(negedge vif.pready);
  317. vif.penable <= 1'b0;
  318. tr.PSLVERR = vif.pslverr;
  319. end
  320. else if(tr.op == readd)
  321. begin
  322. vif.psel <= 1'b1;
  323. vif.paddr <= tr.PADDR;
  324. vif.presetn <= 1'b1;
  325. vif.pwrite <= 1'b0;
  326. @(posedge vif.pclk);
  327. vif.penable <= 1'b1;
  328. `uvm_info("DRV", $sformatf("mode:%0s, addr:%0d, wdata:%0d, rdata:%0d, slverr:%0d",tr.op.name(),tr.PADDR,tr.PWDATA,tr.PRDATA,tr.PSLVERR), UVM_NONE);
  329. @(negedge vif.pready);
  330. vif.penable <= 1'b0;
  331. tr.PRDATA = vif.prdata;
  332. tr.PSLVERR = vif.pslverr;
  333. end
  334. seq_item_port.item_done();
  335. end
  336. endtask
  337. virtual task run_phase(uvm_phase phase);
  338. drive();
  339. endtask
  340. endclass
  341. //////////////////////////////////////////////////////////////////
  342. class mon extends uvm_monitor;
  343. `uvm_component_utils(mon)
  344. uvm_analysis_port#(transaction) send;
  345. transaction tr;
  346. virtual apb_if vif;
  347. function new(input string inst = "mon", uvm_component parent = null);
  348. super.new(inst,parent);
  349. endfunction
  350. virtual function void build_phase(uvm_phase phase);
  351. super.build_phase(phase);
  352. tr = transaction::type_id::create("tr");
  353. send = new("send", this);
  354. if(!uvm_config_db#(virtual apb_if)::get(this,"","vif",vif))//uvm_test_top.env.agent.drv.aif
  355. `uvm_error("MON","Unable to access Interface");
  356. endfunction
  357. virtual task run_phase(uvm_phase phase);
  358. forever begin
  359. @(posedge vif.pclk);
  360. if(!vif.presetn)
  361. begin
  362. tr.op = rst;
  363. `uvm_info("MON", "SYSTEM RESET DETECTED", UVM_NONE);
  364. send.write(tr);
  365. end
  366. else if (vif.presetn && vif.pwrite)
  367. begin
  368. @(negedge vif.pready);
  369. tr.op = writed;
  370. tr.PWDATA = vif.pwdata;
  371. tr.PADDR = vif.paddr;
  372. tr.PSLVERR = vif.pslverr;
  373. `uvm_info("MON", $sformatf("DATA WRITE addr:%0d data:%0d slverr:%0d",tr.PADDR,tr.PWDATA,tr.PSLVERR), UVM_NONE);
  374. send.write(tr);
  375. end
  376. else if (vif.presetn && !vif.pwrite)
  377. begin
  378. @(negedge vif.pready);
  379. tr.op = readd;
  380. tr.PADDR = vif.paddr;
  381. tr.PRDATA = vif.prdata;
  382. tr.PSLVERR = vif.pslverr;
  383. `uvm_info("MON", $sformatf("DATA READ addr:%0d data:%0d slverr:%0d",tr.PADDR, tr.PRDATA,tr.PSLVERR), UVM_NONE);
  384. send.write(tr);
  385. end
  386. end
  387. endtask
  388. endclass
  389. /////////////////////////////////////////////////////////////////////
  390. class sco extends uvm_scoreboard;
  391. `uvm_component_utils(sco)
  392. uvm_analysis_imp#(transaction,sco) recv;
  393. bit [31:0] arr[32] = '{default:0};
  394. bit [31:0] addr = 0;
  395. bit [31:0] data_rd = 0;
  396. function new(input string inst = "sco", uvm_component parent = null);
  397. super.new(inst,parent);
  398. endfunction
  399. virtual function void build_phase(uvm_phase phase);
  400. super.build_phase(phase);
  401. recv = new("recv", this);
  402. endfunction
  403. virtual function void write(transaction tr);
  404. if(tr.op == rst)
  405. begin
  406. `uvm_info("SCO", "SYSTEM RESET DETECTED", UVM_NONE);
  407. end
  408. else if (tr.op == writed)
  409. begin
  410. if(tr.PSLVERR == 1'b1)
  411. begin
  412. `uvm_info("SCO", "SLV ERROR during WRITE OP", UVM_NONE);
  413. end
  414. else
  415. begin
  416. arr[tr.PADDR] = tr.PWDATA;
  417. `uvm_info("SCO", $sformatf("DATA WRITE OP addr:%0d, wdata:%0d arr_wr:%0d",tr.PADDR,tr.PWDATA, arr[tr.PADDR]), UVM_NONE);
  418. end
  419. end
  420. else if (tr.op == readd)
  421. begin
  422. if(tr.PSLVERR == 1'b1)
  423. begin
  424. `uvm_info("SCO", "SLV ERROR during READ OP", UVM_NONE);
  425. end
  426. else
  427. begin
  428. data_rd = arr[tr.PADDR];
  429. if (data_rd == tr.PRDATA)
  430. `uvm_info("SCO", $sformatf("DATA MATCHED : addr:%0d, rdata:%0d",tr.PADDR,tr.PRDATA), UVM_NONE)
  431. else
  432. `uvm_info("SCO",$sformatf("TEST FAILED : addr:%0d, rdata:%0d data_rd_arr:%0d",tr.PADDR,tr.PRDATA,data_rd), UVM_NONE)
  433. end
  434. end
  435. $display("----------------------------------------------------------------");
  436. endfunction
  437. endclass
  438. /////////////////////////////////////////////////////////////////////
  439. class agent extends uvm_agent;
  440. `uvm_component_utils(agent)
  441. abp_config cfg;
  442. function new(input string inst = "agent", uvm_component parent = null);
  443. super.new(inst,parent);
  444. endfunction
  445. driver d;
  446. uvm_sequencer#(transaction) seqr;
  447. mon m;
  448. virtual function void build_phase(uvm_phase phase);
  449. super.build_phase(phase);
  450. cfg = abp_config::type_id::create("cfg");
  451. m = mon::type_id::create("m",this);
  452. if(cfg.is_active == UVM_ACTIVE)
  453. begin
  454. d = driver::type_id::create("d",this);
  455. seqr = uvm_sequencer#(transaction)::type_id::create("seqr", this);
  456. end
  457. endfunction
  458. virtual function void connect_phase(uvm_phase phase);
  459. super.connect_phase(phase);
  460. if(cfg.is_active == UVM_ACTIVE) begin
  461. d.seq_item_port.connect(seqr.seq_item_export);
  462. end
  463. endfunction
  464. endclass
  465. //////////////////////////////////////////////////////////////////////////////////
  466. class env extends uvm_env;
  467. `uvm_component_utils(env)
  468. function new(input string inst = "env", uvm_component c);
  469. super.new(inst,c);
  470. endfunction
  471. agent a;
  472. sco s;
  473. virtual function void build_phase(uvm_phase phase);
  474. super.build_phase(phase);
  475. a = agent::type_id::create("a",this);
  476. s = sco::type_id::create("s", this);
  477. endfunction
  478. virtual function void connect_phase(uvm_phase phase);
  479. super.connect_phase(phase);
  480. a.m.send.connect(s.recv);
  481. endfunction
  482. endclass
  483. //////////////////////////////////////////////////////////////////////////
  484. class test extends uvm_test;
  485. `uvm_component_utils(test)
  486. function new(input string inst = "test", uvm_component c);
  487. super.new(inst,c);
  488. endfunction
  489. env e;
  490. write_read wrrd;
  491. writeb_readb wrrdb;
  492. write_data wdata;
  493. read_data rdata;
  494. write_err werr;
  495. read_err rerr;
  496. reset_dut rstdut;
  497. virtual function void build_phase(uvm_phase phase);
  498. super.build_phase(phase);
  499. e = env::type_id::create("env",this);
  500. wrrd = write_read::type_id::create("wrrd");
  501. wdata = write_data::type_id::create("wdata");
  502. rdata = read_data::type_id::create("rdata");
  503. wrrdb = writeb_readb::type_id::create("wrrdb");
  504. werr = write_err::type_id::create("werr");
  505. rerr = read_err::type_id::create("rerr");
  506. rstdut = reset_dut::type_id::create("rstdut");
  507. endfunction
  508. virtual task run_phase(uvm_phase phase);
  509. phase.raise_objection(this);
  510. wrrdb.start(e.a.seqr);
  511. #20;
  512. phase.drop_objection(this);
  513. endtask
  514. endclass
  515. //////////////////////////////////////////////////////////////////////
  516. module tb;
  517. apb_if vif();
  518. apb_ram dut (.presetn(vif.presetn), .pclk(vif.pclk), .psel(vif.psel), .penable(vif.penable), .pwrite(vif.pwrite), .paddr(vif.paddr), .pwdata(vif.pwdata), .prdata(vif.prdata), .pready(vif.pready), .pslverr(vif.pslverr));
  519. initial begin
  520. vif.pclk <= 0;
  521. end
  522. always #10 vif.pclk <= ~vif.pclk;
  523. initial begin
  524. uvm_config_db#(virtual apb_if)::set(null, "*", "vif", vif);
  525. run_test("test");
  526. end
  527. initial begin
  528. $dumpfile("dump.vcd");
  529. $dumpvars;
  530. end
  531. endmodule