Vivado 2019.2でUVMが使えるようになっていたので試してみた話。 各種サンプルに記載があるuvm_config_dbにvirtual interfaceを指定するようなテストベンチを実行しようとするとxelabがsegmentation faultを起こす模様。
環境
Ubuntu 18.04 Vivado 2019.2 UVM 1.2
テストベンチ
色々確認した後があって汚いけど以下の通り
`timescale 1ns/1ps
module tb_uvm_test;
`include "uvm_macros.svh"
import uvm_pkg::*;
class sample_seq_item extends uvm_sequence_item;
rand logic [7:0] addr, data;
`uvm_object_utils_begin(sample_seq_item)
`uvm_field_int (addr, UVM_DEFAULT)
`uvm_field_int (data, UVM_DEFAULT)
`uvm_object_utils_end
function new (string name = "sample_seq_item_inst");
super.new(name);
endfunction : new
endclass
class sample_sequencer extends uvm_sequencer #(sample_seq_item);
`uvm_component_utils(sample_sequencer)
`uvm_new_func
task run_phase(uvm_phase phase);
uvm_report_info("SEQR","Hi I am Sequencer");
endtask
endclass
interface sample_if(input logic clk, rstz);
logic[7:0] addr,data;
logic valid;
endinterface
class sample_driver extends uvm_driver #(sample_seq_item);
`uvm_component_utils(sample_driver)
// virtual sample_if vif;
function new (string name ="sample_driver", uvm_component parent);
super.new(name, parent);
endfunction
// function void build_phase(uvm_phase phase);
// super.build_phase(phase);
// if(!uvm_config_db#(virtual sample_if)::get(this, "", "vif", vif))
// `uvm_fatal("NOVIF",{"virtual interface must be set for: ",get_full_name(),".vif"});
// endfunction: build_phase
task run_phase(uvm_phase phase);
uvm_report_info("DRIVER", "Hi! I am sample_driver");
// sample_seq_item trans_item;
// vif.valid = 1'b0;
// @(posedge cif.rstz);// wait negate reset
// forever begin
// seq_item_port.get_next_item(trans_item);
// // get several value from trans_item and drive
// // signals, receive signals via virtual interface
// @(posedge vif.clk);
// vif.valid <= 1'b1;
// vif.addr <= trans_item.addr;
// vif.data <= trans_item.data;
// @(posedge vif.clk) vif.valid <= 1'b0;
// seq_item_port.item_done();
// end
endtask
endclass
class sample_monitor extends uvm_monitor;
`uvm_component_utils(sample_monitor)
// virtual sample_if vif;
function new(string name="sample_monitor", uvm_component parent);
super.new(name, parent);
endfunction
// function void build_phase(uvm_phase phase);
// super.build_phase(phase);
// if(!uvm_config_db#(virtual sample_if)::get(this, "", "vif", vif))
// `uvm_fatal("NOVIF",{"virtual interface must be set for:", get_full_name(), ".vif"});
// endfunction: build_phase
task run_phase(uvm_phase phase);
uvm_report_info("MONITOR","Hi! I am sample_monitor");
// fork
// //check_clock;
// check_trans;
// join
endtask
// task check_trans;
// forever begin
// @(posedge vif.valid) uvm_report_info("MON", $sformatf("addr=%02Xh, data=%02Xh", vif.addr, vif.data));
// end
// endtask;
// task check_clock;
// forever begin
// wait(vif.clk===1'b0);
// uvm_report_info("MON", "fall clock");
// wait(vif.clk===1'b1);
// uvm_report_info("MON", "rise clock");
// end
// endtask
endclass
class sample_agent extends uvm_agent;
`uvm_component_utils(sample_agent)
`uvm_new_func
sample_driver driver;
sample_sequencer sequencer;
sample_monitor monitor;
function void build_phase(uvm_phase phase);
driver = sample_driver::type_id::create("driver",this);
sequencer = sample_sequencer::type_id::create("sequencer",this);
monitor = sample_monitor::type_id::create("monitor",this);
endfunction
function void connect_phase(uvm_phase phase);
if(get_is_active() == UVM_ACTIVE) begin
driver.seq_item_port.connect(sequencer.seq_item_export);
end
endfunction
task run_phase(uvm_phase phase);
uvm_report_info("AGENT", "Hi! I am Agent");
endtask
endclass
class sample_env extends uvm_env;
`uvm_component_utils(sample_env)
`uvm_new_func
sample_agent agent;
function void build_phase(uvm_phase phase);
super.build_phase(phase);
agent = sample_agent::type_id::create("agent",this);
endfunction
endclass
// virtual class sample_base_sequence extends uvm_sequence #(sample_seq_item);
// function new(string name="sample_base_seq");
// super.new(name);
// endfunction
// virtual task pre_body();
// if(starting_phase != null) begin
// `uvm_info(get_type_name(),
// $sformatf("%s pre_body() raising %s objection",
// starting_phase.get_name()), UVM_MEDIUM);
// starting_phase.raise_objection(this);
// end
// endtask
// // Drop the objection in the post_body so the objection is removed when
// // the root sequence is complete.
// virtual task post_body();
// if(starting_phase != null) begin
// `uvm_info(get_type_name(),
// $sformatf("%s post_bodu() dropping %s objection",
// get_sequence_path(),
// starting_phase.get_name()), UVM_MEDIUM);
// starting_phase.drop_objection(this);
// end
// endtask
// endclass
// class issue_one_trans_seq extends sample_base_sequence;
// function new(string name="issue_one_trans_seq", uvm_component parent);
// super.new(name,parent);
// endfunction
// `uvm_object_utils(issue_one_trans_seq)
// virtual task body();
// sample_seq_item trans_item;
// $display("I am issue_one_trans_seq");
// `uvm_create(trans_item)
// trans_item.addr = 8'h00;
// trans_item.data = 8'h10;
// `uvm_send(trans_item)
// #1000 ns;
// endtask
// endclass
// class test extends uvm_test;
// `uvm_component_utils(test)
// `uvm_new_func
// sample_env env;
// virtual function void build_phase(uvm_phase phase);
// uvm_config_db#(uvm_object_wrapper)::set(this,
// "env.agent.sequener.run_phase", "default_sequence",
// issue_one_trans_seq::type_id::get());
// env=sample_env::type_id::create("env",this);
// super.build_phase(phase);
// endfunction
// endclass
class sample_test extends uvm_test;
`uvm_component_utils(sample_test)
sample_env env;
function new (string name="sample_test", uvm_component parent=null);
super.new(name,parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
env = sample_env::type_id::create("env",this);
endfunction
task run_phase(uvm_phase phase);
uvm_report_info("TEST", "Hello World from sample_test");
endtask
endclass
logic clk, rstz;
sample_if sif(clk, rstz);// interface
initial begin
fork
begin
clk = 1'b1;
#100;
forever #50 clk = ~clk;
end
begin
rstz = 1'b0;
#100;
rstz = 1'b1;
end
join
end
class my_class;
function new();
endfunction
endclass
initial begin
my_class mc = new;
`uvm_info("info", "Hello World from initial block", UVM_LOW)
uvm_config_db #(virtual sample_if)::set(uvm_root::get(), "*.env.*", "vif", sif);//xelab segmentation fault.
run_test("sample_test");
end
endmodule
実行メッセージ
[1/3] Generating sim/work/xsim/compile_tb_uvm_test.timestamp
tb_uvm_test.sh - Script generated by export_simulation (Vivado v2019.2 (64-bit)-id)
INFO: [VRFC 10-2263] Analyzing SystemVerilog file "/home/akira/work/hls/ICS_IF/test/src/tb_uvm_test.sv" into library xil_defaultlib
INFO: [VRFC 10-311] analyzing module tb_uvm_test
WARNING: [VRFC 10-3824] variable 'mc' must explicitly be declared as automatic or static [/home/akira/work/hls/ICS_IF/test/src/tb_uvm_test.sv:208]
INFO: [VRFC 10-2263] Analyzing Verilog file "/home/akira/work/hls/ICS_IF/build/sim/work/tb_uvm_test/xsim/glbl.v" into library xil_defaultlib
INFO: [VRFC 10-311] analyzing module glbl
[2/3] Generating sim/work/xsim/elaborate_tb_uvm_test.timestamp
FAILED: sim/work/xsim/elaborate_tb_uvm_test.timestamp
cd /home/akira/work/hls/ICS_IF/build/sim/work/xsim && source ./elaborate_tb_uvm_test.sh -noclean_files && /opt/Xilinx/Vitis/2019.2/tps/lnx64/cmake-3.3.2/bin/cmake -E touch elaborate_tb_uvm_test.timestamp
tb_uvm_test.sh - Script generated by export_simulation (Vivado v2019.2 (64-bit)-id)
Vivado Simulator 2019.2
Copyright 1986-1999, 2001-2019 Xilinx, Inc. All Rights Reserved.
Running: /opt/Xilinx/Vivado/2019.2/bin/unwrapped/lnx64.o/xelab --relax -L uvm --debug typical --mt auto -L xil_defaultlib -L xilinx_vip -L unisims_ver -L unimacro_ver -L secureip -L xpm --snapshot tb_uvm_test xil_defaultlib.tb_uvm_test xil_defaultlib.glbl -log tb_uvm_test_elaborate.log
Multi-threading is on. Using 2 slave threads.
Starting static elaboration
Pass Through NonSizing Optimizer
/opt/Xilinx/Vivado/2019.2/bin/loader: line 280: 1102 Segmentation fault (core dumped) "$RDI_PROG" "$@"
ninja: build stopped: subcommand failed.
回避策
このままだとconnect_phaseでインターフェースの接続ができないので、検討中。 独自クラスのインスタンスは渡せてるっぽいのでこれを使えばインターフェースの受け渡しも可能か? 素直にバージョンアップ待つのが賢明な気もするけど。
interfaceをmodule内で定義しているのがどうもだめだった模様。 モジュールの外側で定義したら問題なく動いた。 この例が動いたので差分チェックして見つけた。
参考ページ
https://sites.google.com/site/playsystemverilog/uvm/uvm-introduction-for-10days https://www.accellera.org/images/downloads/standards/uvm/uvm_users_guide_1.2.pdf https://forums.xilinx.com/t5/Simulation-and-Verification/XELAB-2019-2-elaboration-fails-for-simple-UVM-example-design/m-p/1113039
0 件のコメント:
コメントを投稿