tb_uvm.sv UVM
// UVM tối thiểu: item/sequence/driver/monitor/scoreboard/agent/env/test,// config_db truyền virtual interface, factory override, objection.`include "uvm_macros.svh"interface reg_if (input logic clk); logic we; logic [7:0] wdata; logic [7:0] q;endinterfacemodule dut (reg_if bus); // thanh ghi 8-bit đơn giản always_ff @(posedge bus.clk) if (bus.we) bus.q <= bus.wdata;endmodulepackage tb_pkg; import uvm_pkg::*; class item extends uvm_sequence_item; rand bit [7:0] data; `uvm_object_utils(item) function new(string name = "item"); super.new(name); endfunction endclass class item_odd extends item; // dùng để thử factory override constraint c_odd { data[0] == 1; } `uvm_object_utils(item_odd) function new(string name = "item_odd"); super.new(name); endfunction endclass class seq extends uvm_sequence #(item); `uvm_object_utils(seq) function new(string name = "seq"); super.new(name); endfunction task body(); repeat (8) begin item it = item::type_id::create("it"); start_item(it); if (!it.randomize()) `uvm_error("SEQ", "randomize failed") finish_item(it); end endtask endclass class drv extends uvm_driver #(item); `uvm_component_utils(drv) virtual reg_if vif; function new(string n, uvm_component p); super.new(n, p); endfunction function void build_phase(uvm_phase phase); if (!uvm_config_db#(virtual reg_if)::get(this, "", "vif", vif)) `uvm_fatal("DRV", "no vif") endfunction task run_phase(uvm_phase phase); vif.we <= 0; forever begin seq_item_port.get_next_item(req); @(negedge vif.clk); vif.we <= 1; vif.wdata <= req.data; @(negedge vif.clk); vif.we <= 0; seq_item_port.item_done(); end endtask endclass class mon extends uvm_monitor; `uvm_component_utils(mon) virtual reg_if vif; uvm_analysis_port #(item) ap; function new(string n, uvm_component p); super.new(n, p); ap = new("ap", this); endfunction function void build_phase(uvm_phase phase); void'(uvm_config_db#(virtual reg_if)::get(this, "", "vif", vif)); endfunction task run_phase(uvm_phase phase); forever begin @(posedge vif.clk); if (vif.we) begin item t = item::type_id::create("t"); t.data = vif.wdata; ap.write(t); end end endtask endclass class sb extends uvm_scoreboard; `uvm_component_utils(sb) uvm_analysis_imp #(item, sb) imp; int n, odd; function new(string n_, uvm_component p); super.new(n_, p); imp = new("imp", this); endfunction function void write(item t); n++; odd += t.data[0]; endfunction function void report_phase(uvm_phase phase); `uvm_info("SB", $sformatf("C12 RESULT observed=%0d odd=%0d (override → expect odd==observed==8)", n, odd), UVM_NONE) endfunction endclass class env extends uvm_env; `uvm_component_utils(env) uvm_sequencer #(item) sqr; drv d; mon m; sb s; function new(string n, uvm_component p); super.new(n, p); endfunction function void build_phase(uvm_phase phase); sqr = uvm_sequencer#(item)::type_id::create("sqr", this); d = drv::type_id::create("d", this); m = mon::type_id::create("m", this); s = sb::type_id::create("s", this); endfunction function void connect_phase(uvm_phase phase); d.seq_item_port.connect(sqr.seq_item_export); m.ap.connect(s.imp); endfunction endclass class test extends uvm_test; `uvm_component_utils(test) env e; function new(string n, uvm_component p); super.new(n, p); endfunction function void build_phase(uvm_phase phase); item::type_id::set_type_override(item_odd::get_type()); e = env::type_id::create("e", this); endfunction task run_phase(uvm_phase phase); seq s = seq::type_id::create("s"); phase.raise_objection(this); s.start(e.sqr); #20; phase.drop_objection(this); endtask endclassendpackagemodule tb; import uvm_pkg::*; import tb_pkg::*; logic clk = 0; always #5 clk = ~clk; reg_if bus(clk); dut u(bus); initial begin uvm_config_db#(virtual reg_if)::set(null, "*", "vif", bus); run_test("test"); endendmodule
Đã kiểm chứng thế nào
- ✓Phân tích và elaborate theo LRM (pyslang 12.1.0)
- ✓Elaborate cùng thư viện Accellera UVM (pyslang 12.1.0)
- ✓Mô phỏng, exit 0 và output khớp kỳ vọng tính tay (Verilator 5.050, 2-state)
Output phải khớp: C12 RESULT observed=8 odd=8^UVM_ERROR :\s+0$^UVM_FATAL :\s+0$
Mô phỏng bằng Verilator 5.050 + Accellera uvm-core 2020.3.1 với +define+UVM_NO_DPI: tắt kiểm tra tên component bằng regex và các hàm DPI (uvm_hdl backdoor, regex). 2 UVM_WARNING (NO_DPI_USED, NO_VISIT_CHECK) là dự kiến.
Các kiểm tra chạy lúc xây dựng nội dung (2026-11-06), không chạy trong trình duyệt. Kỳ vọng được tính tay trước khi chạy.