UVM实战--带有寄存器的加法器
一.整体的设计结构图
这里将DUT换成加法器,可以理解为之前UVM加法器加上寄存器,这里总线的功能不做修改,目的看代码的移植那些部分需要修改。
二.各个组件代码详解
2.1 DUT
module dut(
input clk,
input rst_n,
input bus_cmd_valid,//为1时表示数据有效,只持续一个时钟
input bus_op,//1时为写。0时为读
input [15:0] bus_addr,//地址
input [15:0] bus_wr_data,//读取的数据
output [15:0] bus_rd_data,//写入的数据input [7:0] a,
input [7:0] b,
input cin,
input enable,output [7:0] sum,
output enable1,
output cout,
reg invert
);//如果invert为1翻转,否则直接输出
always @(posedge clk) beginif(!rst_n) beginsum <= 8'b0;cout <= 1'b0;enable1 <= 1'b0;endelse if(invert) begin{cout,sum} <= ~a + ~b + ~cin;enable1 <= enable;endelse beginenable1 <= enable;{cout,sum} <= a + b + cin;end
endalways @(posedge clk) beginif(!rst_n) invert <= 1'b0;else if(bus_cmd_valid && bus_op) begincase(bus_addr)16'h9: begininvert <= bus_wr_data[0];enddefault: beginendendcaseend
endreg [15:0] bus_rd_data;
always @(posedge clk) beginif(!rst_n)bus_rd_data <= 16'b0;else if(bus_cmd_valid && !bus_op) begincase(bus_addr)16'h9: beginbus_rd_data <= {15'b0, invert};enddefault: beginbus_rd_data <= 16'b0; endendcaseend
endendmodule
2.2 bus_driver.sv
`ifndef BUS_DRIVER__SV
`define BUS_DRIVER__SV
class bus_driver extends uvm_driver#(bus_transaction);virtual bus_if vif;`uvm_component_utils(bus_driver)function new(string name = "bus_driver", uvm_component parent = null);super.new(name, parent);endfunctionvirtual function void build_phase(uvm_phase phase);super.build_phase(phase);if(!uvm_config_db#(virtual bus_if)::get(this, "", "vif", vif))`uvm_fatal("bus_driver", "virtual interface must be set for vif!!!")endfunctionextern task run_phase(uvm_phase phase);extern task drive_one_pkt(bus_transaction tr);
endclasstask bus_driver::run_phase(uvm_phase phase);vif.bus_cmd_valid <= 1'b0;vif.bus_op <= 1'b0;vif.bus_addr <= 15'b0;vif.bus_wr_data <= 15'b0;while(!vif.rst_n)@(posedge vif.clk);while(1) beginseq_item_port.get_next_item(req);drive_one_pkt(req);seq_item_port.item_done();end
endtasktask bus_driver::drive_one_pkt(bus_transaction tr);`uvm_info("bus_driver", "begin to drive one pkt", UVM_LOW);repeat(1) @(posedge vif.clk);vif.bus_cmd_valid <= 1'b1;vif.bus_op <= ((tr.bus_op == BUS_RD) ? 0 : 1);vif.bus_addr = tr.addr;vif.bus_wr_data <= ((tr.bus_op == BUS_RD) ? 0 : tr.wr_data);@(posedge vif.clk);vif.bus_cmd_valid <= 1'b0;vif.bus_op <= 1'b0;vif.bus_addr <= 15'b0;vif.bus_wr_data <= 15'b0;@(posedge vif.clk);if(tr.bus_op == BUS_RD) begintr.rd_data = vif.bus_rd_data; //$display("@%0t, rd_data is %0h", $time, tr.rd_data);end//`uvm_info("bus_driver", "end drive one pkt", UVM_LOW);
endtask`endif
2.3 bus_sequencer.sv
`ifndef BUS_SEQUENCER__SV
`define BUS_SEQUENCER__SVclass bus_sequencer extends uvm_sequencer #(bus_transaction);function new(string name, uvm_component parent);super.new(name, parent);endfunction `uvm_component_utils(bus_sequencer)
endclass`endif
2.4 bus_monitor
`ifndef BUS_MONITOR__SV
`define BUS_MONITOR__SV
class bus_monitor extends uvm_monitor;virtual bus_if vif;uvm_analysis_port #(bus_transaction) ap;`uvm_component_utils(bus_monitor)function new(string name = "bus_monitor", uvm_component parent = null);super.new(name, parent);endfunctionvirtual function void build_phase(uvm_phase phase);super.build_phase(phase);if(!uvm_config_db#(virtual bus_if)::get(this, "", "vif", vif))`uvm_fatal("bus_monitor", "virtual interface must be set for vif!!!")ap = new("ap", this);endfunctionextern task main_phase(uvm_phase phase);extern task collect_one_pkt(bus_transaction tr);
endclasstask bus_monitor::main_phase(uvm_phase phase);bus_transaction tr;while(1) begintr = new("tr");collect_one_pkt(tr);ap.write(tr);end
endtasktask bus_monitor::collect_one_pkt(bus_transaction tr);while(1) begin@(posedge vif.clk);if(vif.bus_cmd_valid) break;endtr.bus_op = ((vif.bus_op == 0) ? BUS_RD : BUS_WR);tr.addr = vif.bus_addr;tr.wr_data = vif.bus_wr_data;@(posedge vif.clk);tr.rd_data = vif.bus_rd_data;`uvm_info("bus_monitor", "end collect one pkt", UVM_LOW);
endtask`endif
2.5 bus_agent.sv
`ifndef BUS_AGENT__SV
`define BUS_AGENT__SVclass bus_agent extends uvm_agent ;bus_sequencer sqr;bus_driver drv;bus_monitor mon;uvm_analysis_port #(bus_transaction) ap;function new(string name, uvm_component parent);super.new(name, parent);endfunction extern virtual function void build_phase(uvm_phase phase);extern virtual function void connect_phase(uvm_phase phase);`uvm_component_utils(bus_agent)
endclass function void bus_agent::build_phase(uvm_phase phase);super.build_phase(phase);if (is_active == UVM_ACTIVE) beginsqr = bus_sequencer::type_id::create("sqr", this);drv = bus_driver::type_id::create("drv", this);endmon = bus_monitor::type_id::create("mon", this);
endfunction function void bus_agent::connect_phase(uvm_phase phase);super.connect_phase(phase);if (is_active == UVM_ACTIVE) begindrv.seq_item_port.connect(sqr.seq_item_export);endap = mon.ap;
endfunction`endif
2.6 bus_transaction.sv
`ifndef BUS_TRANSACTION__SV
`define BUS_TRANSACTION__SVtypedef enum{BUS_RD, BUS_WR} bus_op_e;class bus_transaction extends uvm_sequence_item;rand bit[15:0] rd_data;rand bit[15:0] wr_data;rand bit[15:0] addr;rand bus_op_e bus_op;`uvm_object_utils_begin(bus_transaction)`uvm_field_int(rd_data, UVM_ALL_ON)`uvm_field_int(wr_data, UVM_ALL_ON)`uvm_field_int(addr , UVM_ALL_ON)`uvm_field_enum(bus_op_e, bus_op, UVM_ALL_ON)`uvm_object_utils_endfunction new(string name = "bus_transaction");super.new();endfunctionendclass
`endif
2.7 bus_if
`ifndef BUS_IF__SV
`define BUS_IF__SVinterface bus_if(input clk, input rst_n);logic bus_cmd_valid;logic bus_op;logic [15:0] bus_addr;logic [15:0] bus_wr_data;logic [15:0] bus_rd_data;endinterface`endif
2.8 my_if
`ifndef MY_IF__SV
`define MY_IF__SVinterface my_if(input clk, input rst_n);logic [7:0] a;logic [7:0] b;logic cin;logic enable;wire enable1;wire [7:0] sum;wire cout;endinterface
`endif
2.9 my_driver
`ifndef MY_DRIVER__SV
`define MY_DRIVER__SV
class my_driver extends uvm_driver;virtual my_if vif;`uvm_component_utils(my_driver)function new(string name = "my_driver",uvm_component parent = null);super.new(name,parent);endfunctionvirtual function void build_phase(uvm_phase phase);super.build_phase(phase);if(!uvm_config_db#(virtual my_if)::get(this,"","vif",vif))`uvm_fatal("my_driver","virtual interface must be set for vif!!!")endfunctionextern task mian_phase(uvm_phase phase);extern task drive_one_pkt(my_transaction_i tr);
endclasstask my_driver::mian_phase(uvm_phase phase);vif.a <= 8'b0;vif.b <= 8,b0;vif.cin <= 1'b0;vif.enable <= 1'b0;while(!vif.rst_n)begin@(posedge vif.clk);endwhile(1)beginseq_item_port.get_next_item(req);drive_one_pkt(req);seq_item_port.item_done();end
endtasktask my_driver::drive_one_pkt(my_transcation_i tr);uvm_info("my_driver","begin to dirve one pkt",UVM_LOW);@(posedge vif.clk);vif.a <= tr.a;vif.b <= tr.b;vif.cin <= tr.cin;vif.enable <= 1'b1;@(posedge vif.clk)vif.enable <= 1'b0;`uvm_info("my_driver","end to drive one pkt",UVM_LOW);
endtask
`endif
2.10 my_transaction_i
`ifdenf MY_TRANSACTION_I__SV
`define MY_TRANSACTION_I__SVclass my_transaction_i extends uvm_sequence_item;rand bit [7:0] a;rand bit [7:0] b;rand bit cin;`uvm_object_utils_begin(my_transaction_i)`uvm_field_int(a,UVM_ALL_ON)`uvm_field_int(b,UVM_ALL_ON)`uvm_field_int(cin,UVM_ALL_ON)`uvm_object_utils_endfunction new(string name = "my_transaction_i");super.new();endfunction
endclass
`endif
2.11 my_transaction_o
`idndef MY_TRANSACTION_O__SV
`define MY_TRANSACTION_O__SVclass my_transaction_o extends uvm_sequence_item;bit [7:0] sum;bit cout;function new(string name = "my_transaction_o")super.new();endfunction
endclass
`endif
2.12 my_sequencer
`ifndef MY_SEQUENCER__SV
`define MY_SEQUENCER__SVclass my_sequencer extends uvm_sequencer #(my_transaction_i);function new(string name,uvm_component parent);super.new(name,parent);endfunction`uvm_component_utils(my_sequencer)
endclass
`endif
2.13 my_monitor_i
`ifndef MY_MONITOR_I__SV
`define MY_MONITOR_I__SVclass my_monitor_i extends uvm_monitor;virtual my_if vif;uvm_analysis_port #(my_transaction_i) ap;`uvm_component_utils(my_monitor_i)function new(string name = "monitor_i",uvm_component parent = null);super.new(name,parent);endfunctionvirtual function void build_phase(uvm_phase phase);super.build_phase(phase);if(!uvm_config_db#(virtual my_if)::get(this,"","vif",vif))`uvm_fatal("my_monitor","virtual interface must be set for vif!!!")ap = new("ap",this);endfunctionextern task main_phase(uvm_phase phase);extern task drive_one_pkt(my_transaction_i tr);
endclasstask my_monitor::main_phase(uvm_phase phase);my_transaction_i tr;while(1) begintr.new("tr");collect_one_pkt(tr);ap.write(tr);end
endtasktask my_monitor::collcet_one_pkt(my_transaction_i tr);
while(1) begin@(posedge vif.clk);if(vif.enable) break;
end`uvm_info("my_monitor","begin to collcet one pkt",UVM_LOW); @(posedge vif.clk);tr.a <= vif.a;tr.b <= vif.b;tr.cin <= vif.cin;`uvm_info("my_monitor","end to collcet one pkt",UVM_LOW);
endtask
`endif
2.14 my_monitor_o
`ifndef MY_MONITOR_O__SV
`define MY_MONITOR_O__SV
class my_monitor_o extends uvm_monitorvirtual my_if vif;uvm_analysis_port #(my_transaction_o) ap;`uvm_component_port #(my_transaction_o) ap;function new(string name = "my_monitor_o",uvm_component parent = null);super.new(name,parent);endfunctionvirtual function void build_phase(uvm_phase phase);super.build_phase(phase);if(!uvm_config_db#(virtual my_if)::get(this,"","vif",vif))`uvm_fatal("my_monitor","virtual interface must be set for vif!!!")ap = new("ap",this);endfunctionextern task main_phase(uvm_phase phase);extern task collcet_one_pkt(my_transaction_i tr);
endclasstask my_monitor::main_phase (uvm_phase phase);my_transaction_o tr;while(1) begintr = new("tr")collcet_one_pkt(tr);ap.write(tr);end
endtasktask my_monitor::collcet_one_pkt(my_transction_o tr);
while(1) begin@(posedge vif.clk)if(vif.enable1) break;
end`uvm_info("my_monitor_o","begin to collcet one pkt",UVM_LOW);@(posedge vif.clk)tr.sum <= vif.sum;tr.cout <= vif.cout;`uvm_info("my_monitor_o","end to collcet one pkt",UVM_ALL);
endtask
`endif
2.15 my_agent_i
`ifndef MY_AGENT_I__SV
`define MY_AGENT_I__SVclass my_agent_i extends uvm_agent;my_sequencer sqr;my_driver drv;my_monitor_i mon_i;`uvm_analysis_port #(my_transaction_i) ap;function new(string name,uvm_component parent);super.new(name,parent);endfunctionextern virtual function void build_phase(uvm_phase phase);extern virtual function void conncet_phase(uvm_phase phase);`uvm_component_utils(my_agent_i)
endclassfunction void my_agent_i::build_phase(uvm_phase phase);super.build_phase(phase);sqr = my_sequencer::type_id::create("sqr",this);drv = my_driver::type_id::create("drv",this);mon_i = my_monitor_i::type_id::create("mon_i",this);
endfunctionfunction void my_agent_i::conncet_phase(uvm_phase phase);super.conncet_phase(phase);drv_seq_item_port.conncet(sqr.seq_item_export);ap = mon.ap;
endfunction
`endif
2.16 my_agent_o
`ifndef MY_AGENT_O__SV
`define MY_AGENT_O__SVclass my_agent_o extends uvm_agent;my_sequencer sqr;my_driver drv;my_monitor_o mon_o;`uvm_analysis_port #(my_transaction_o) ap;function new(string name,uvm_component parent);super.new(name,parent);endfunctionextern virtual function void build_phase(uvm_phase phase);extern virtual function void conncet_phase(uvm_phase phase);`uvm_component_utils(my_agent_o)
endclassfunction void my_agent_o::build_phase(uvm_phase phase);super.build_phase(phase);mon_o = my_monitor_o::type_id::create("mon",this);
endfunctionfunction void my_agent_o::conncet_phase(uvm_phase phase);super.conncet_phase(phase);ap = mon.ap;
endfunction
`endif
2.17 my_scoreboard
`ifndef MY_SCOREBOARD__SV
`define MY_SCOREBOARD__SV
class my_scoreboard extends uvm_scoreboard;my_transaction expect_queue[$];uvm_blocking_get_port #(my_transaction) exp_port;uvm_blocking_get_port #(my_transaction) act_port;`uvm_component_utils(my_scoreboard)extern function new(string name, uvm_component parent = null);extern virtual function void build_phase(uvm_phase phase);extern virtual task main_phase(uvm_phase phase);
endclass function my_scoreboard::new(string name, uvm_component parent = null);super.new(name, parent);
endfunction function void my_scoreboard::build_phase(uvm_phase phase);super.build_phase(phase);exp_port = new("exp_port", this);act_port = new("act_port", this);
endfunction task my_scoreboard::main_phase(uvm_phase phase);my_transaction get_expect, get_actual, tmp_tran;bit result;super.main_phase(phase);fork while (1) beginexp_port.get(get_expect);expect_queue.push_back(get_expect);endwhile (1) beginact_port.get(get_actual);if(expect_queue.size() > 0) begintmp_tran = expect_queue.pop_front();result = get_actual.compare(tmp_tran);if(result) begin `uvm_info("my_scoreboard", "Compare SUCCESSFULLY", UVM_LOW);endelse begin`uvm_error("my_scoreboard", "Compare FAILED");$display("the expect pkt is");tmp_tran.print();$display("the actual pkt is");get_actual.print();endendelse begin`uvm_error("my_scoreboard", "Received from DUT, while Expect Queue is empty");$display("the unexpected pkt is");get_actual.print();end endjoin
endtask
`endif
2.18 my_env
`ifndef MY_ENV__SV
`define MY_ENV__SVclass my_env extends uvm_env;my_agent_i i_agt;my_agent_o o_agt;bus_agent bus_agt;my_model mdl;my_scoreboard scb;reg_model p_rm;uvm_tlm_analysis_fifo #(my_transaction) agt_scb_fifo;uvm_tlm_analysis_fifo #(my_transaction) agt_mdl_fifo;uvm_tlm_analysis_fifo #(my_transaction) mdl_scb_fifo;function new(string name = "my_env", uvm_component parent);super.new(name, parent);endfunctionvirtual function void build_phase(uvm_phase phase);super.build_phase(phase);i_agt = my_agent::type_id::create("i_agt", this);o_agt = my_agent::type_id::create("o_agt", this);bus_agt = bus_agent::type_id::create("bus_agt", this);bus_agt.is_active = UVM_ACTIVE;mdl = my_model::type_id::create("mdl", this);scb = my_scoreboard::type_id::create("scb", this);agt_scb_fifo = new("agt_scb_fifo", this);agt_mdl_fifo = new("agt_mdl_fifo", this);mdl_scb_fifo = new("mdl_scb_fifo", this);endfunctionextern virtual function void connect_phase(uvm_phase phase);`uvm_component_utils(my_env)
endclassfunction void my_env::connect_phase(uvm_phase phase);super.connect_phase(phase);i_agt.ap.connect(agt_mdl_fifo.analysis_export);mdl.port.connect(agt_mdl_fifo.blocking_get_export);mdl.ap.connect(mdl_scb_fifo.analysis_export);scb.exp_port.connect(mdl_scb_fifo.blocking_get_export);o_agt.ap.connect(agt_scb_fifo.analysis_export);scb.act_port.connect(agt_scb_fifo.blocking_get_export); mdl.p_rm = this.p_rm;
endfunction`endif
2.19 my_model
`ifndef MY_MODEL__SV
`define MY_MODEL__SVclass my_model extends uvm_component;uvm_blocking_get_port #(my_transaction_i) port;uvm_analysis_port #(my_transaction_o) ap;extern function new(string name,uvm_component parent);extern function void build_phase(uvm_phase phase);extern virtual task main_phase(uvm_phase phase);extern virtual function void invert_tr(my_transaction_o tr2);`uvm_component_utils(my_model)
endclassfunction my_model::new(string name,uvm_component parent);super.new(name,parent);
endfunctionfunction void my_model::build_phase(uvm_phase phase);super.build_phase(phase);port = new("port",this);ap = new("ap",this);
endfunctionfunction void my_model::invert_tr(my_transaction_o tr2);tr2.sum = tr2.sum ^ 8'hFF;tr2.cout = tr2.cout ^ 1'b1;
endfunction
task my_model::main_phase(uvm_phase phase);my_transaction_i tr;my_transaction_o tr2;uvm_state_e states;uvm_reg_data_t value;bit [8:0] sum_total;super.main_phase(phase);p_rm.invert.read(status,value,UVM_FRONTDOOR);while(1)beginport.get(tr);tr2 = new("tr2");sum_total = tr.a+tr.b+tr.cin;tr2.sum = sum_total[7:0];tr2.cout = sum_total[8];is(value)invert_tr(tr2);`uvm_info("my_model", "get transactions, add and print it:", UVM_LOW)tr2.print();ap.write(tr2);end
endtask
`endif
2.20 my_env
`ifndef MY_ENV__SV
`define MY_ENV__SVclass my_env extends uvm_env;my_agent_i i_agt;my_agent_o o_agt;bus_agent bus_agt;my_model mdl;my_scoreboard scb;reg_model p_rm;uvm_tlm_analysis_fifo #(my_transaction_o) agt_scb_fifo;uvm_tlm_analysis_fifo #(my_transaction_i) agt_mdl_fifo;uvm_tlm_analysis_fifo #(my_transaction_o) mdl_scb_fifo;function new(string name = "my_env", uvm_component parent);super.new(name, parent);endfunctionvirtual function void build_phase(uvm_phase phase);super.build_phase(phase);i_agt = my_agent::type_id::create("i_agt", this);o_agt = my_agent::type_id::create("o_agt", this);bus_agt = bus_agent::type_id::create("bus_agt", this);bus_agt.is_active = UVM_ACTIVE;mdl = my_model::type_id::create("mdl", this);scb = my_scoreboard::type_id::create("scb", this);agt_scb_fifo = new("agt_scb_fifo", this);agt_mdl_fifo = new("agt_mdl_fifo", this);mdl_scb_fifo = new("mdl_scb_fifo", this);endfunctionextern virtual function void connect_phase(uvm_phase phase);`uvm_component_utils(my_env)
endclassfunction void my_env::connect_phase(uvm_phase phase);super.connect_phase(phase);i_agt.ap.connect(agt_mdl_fifo.analysis_export);mdl.port.connect(agt_mdl_fifo.blocking_get_export);mdl.ap.connect(mdl_scb_fifo.analysis_export);scb.exp_port.connect(mdl_scb_fifo.blocking_get_export);o_agt.ap.connect(agt_scb_fifo.analysis_export);scb.act_port.connect(agt_scb_fifo.blocking_get_export); mdl.p_rm = this.p_rm;
endfunction`endif
2.21 base_test
`ifndef BASE_TEST__SV
`define BASE_TEST__SVclass base_test extends uvm_test;my_env env;my_vsqr v_sqr;//(2)成员变量的理解reg_model rm;my_adapter reg_sqr_adapter;function new(string name = "base_test", uvm_component parent = null);super.new(name,parent);endfunctionextern virtual function void build_phase(uvm_phase phase);extern virtual function void connect_phase(uvm_phase phase);extern virtual function void report_phase(uvm_phase phase);`uvm_component_utils(base_test)
endclassfunction void base_test::build_phase(uvm_phase phase);super.build_phase(phase);env = my_env::type_id::create("env", this); v_sqr = my_vsqr::type_id::create("v_sqr", this);rm = reg_model::type_id::create("rm", this);rm.configure(null, "");rm.build();rm.lock_model();rm.reset();rm.set_hdl_path_root("top_tb.my_dut");reg_sqr_adapter = new("reg_sqr_adapter");env.p_rm = this.rm;
endfunctionfunction void base_test::connect_phase(uvm_phase phase);super.connect_phase(phase);v_sqr.p_my_sqr = env.i_agt.sqr;v_sqr.p_bus_sqr = env.bus_agt.sqr;v_sqr.p_rm = this.rm;rm.default_map.set_sequencer(env.bus_agt.sqr, reg_sqr_adapter);rm.default_map.set_auto_predict(1);
endfunctionfunction void base_test::report_phase(uvm_phase phase);uvm_report_server server;int err_num;super.report_phase(phase);server = get_report_server();err_num = server.get_severity_count(UVM_ERROR);if (err_num != 0) begin$display("TEST CASE FAILED");endelse begin$display("TEST CASE PASSED");end
endfunction`endif
2.22 reg_model
`ifndef REG_MODEL__SV
`define REG_MODEL__SV
//uvm_reg是比较小的单位,一个寄存器中至少包含一个uvm_reg_field
class reg_invert extends uvm_reg;//uvm_reg_filed是寄存器模型中的最小单位rand uvm_reg_field reg_data;//build的理解virtual function void build();reg_data = uvm_reg_field::type_id::create("reg_data");// parameter: parent, size, lsb_pos, access, volatile, reset value, has_reset, is_rand, individually accessible//(4)configure的参数理解reg_data.configure(this, 1, 0, "RW", 1, 0, 1, 1, 0);endfunction`uvm_object_utils(reg_invert)function new(input string name="reg_invert");//parameter: name, size, has_coverage//(3)new函数的理解super.new(name, 16, UVM_NO_COVERAGE);endfunction
endclassclass reg_counter extends uvm_reg;rand uvm_reg_field reg_data;virtual function void build();reg_data = uvm_reg_field::type_id::create("reg_data");// parameter: parent, size, lsb_pos, access, volatile, reset value, has_reset, is_rand, individually accessiblereg_data.configure(this, 32, 0, "W1C", 1, 0, 1, 1, 0);endfunction`uvm_object_utils(reg_counter)function new(input string name="reg_counter");//parameter: name, size, has_coveragesuper.new(name, 32, UVM_NO_COVERAGE);endfunction
endclass//uvm_reg_block它是一个较大的单位,在其中可以加入很多的uvm_reg,也可以加入其他的uvm_reg_block
class reg_model extends uvm_reg_block;rand reg_invert invert;rand reg_counter counter;virtual function void build();//(5)uvm_reg_mapdefault_map = create_map("default_map", 0, 2, UVM_BIG_ENDIAN, 0);//(6)实例化invert并调用invert.configure函数invert = reg_invert::type_id::create("invert", , get_full_name());invert.configure(this, null, "invert");invert.build();//(7)default_mapdefault_map.add_reg(invert, 'h9, "RW");counter= reg_counter::type_id::create("counter", , get_full_name());counter.configure(this, null, "counter");counter.build();default_map.add_reg(counter, 'h5, "RW");endfunction`uvm_object_utils(reg_model)function new(input string name="reg_model");super.new(name, UVM_NO_COVERAGE);endfunction endclass
`endif
2.23 my_adapter
`ifndef MY_ADAPTER__SV
`define MY_ADAPTER__SV
//(1)adapter的作用
class my_adapter extends uvm_reg_adapter;string tID = get_type_name();`uvm_object_utils(my_adapter)function new(string name="my_adapter");super.new(name);endfunction : new//reg2bus,其作用为寄存器模型通过sequence发出的uvm_reg_bus_op型的变量转换成bus_sequencer能够接收的形式function uvm_sequence_item reg2bus(const ref uvm_reg_bus_op rw);bus_transaction tr;tr = new("tr"); tr.addr = rw.addr;tr.bus_op = (rw.kind == UVM_READ) ? BUS_RD: BUS_WR;if (tr.bus_op == BUS_WR)tr.wr_data = rw.data; return tr;endfunction : reg2bus//bus2reg,其作用为当监测到总线上有操作时,它将收集来的transaction转换成寄存器模型能够接受的形式,以便寄存器模型能够更新相应的寄存器的值。function void bus2reg(uvm_sequence_item bus_item, ref uvm_reg_bus_op rw);bus_transaction tr;if(!$cast(tr, bus_item)) begin`uvm_fatal(tID,"Provided bus_item is not of the correct type. Expecting bus_transaction")return;endrw.kind = (tr.bus_op == BUS_RD) ? UVM_READ : UVM_WRITE;rw.addr = tr.addr;rw.byte_en = 'h3;rw.data = (tr.bus_op == BUS_RD) ? tr.rd_data : tr.wr_data;rw.status = UVM_IS_OK;endfunction : bus2regendclass : my_adapter
`endif
2.24 my_vsqr
`ifndef MY_VSQR__SV
`define MY_VSQR__SVclass my_vsqr extends uvm_sequencer;my_sequencer p_my_sqr;bus_sequencer p_bus_sqr;reg_model p_rm;function new(string name, uvm_component parent);super.new(name, parent);endfunction `uvm_component_utils(my_vsqr)
endclass`endif
2.25 my_case0
`ifndef MY_CASE0__SV
`define MY_CASE0__SV
class case0_sequence extends uvm_sequence #(my_transaction_i);my_transaction_i m_trans;function new(string name= "case0_sequence");super.new(name);endfunction virtual task body();repeat (10) begin`uvm_do(m_trans)endendtask`uvm_object_utils(case0_sequence)
endclassclass case0_cfg_vseq extends uvm_sequence;`uvm_object_utils(case0_cfg_vseq)`uvm_declare_p_sequencer(my_vsqr)function new(string name= "case0_cfg_vseq");super.new(name);endfunction virtual task body();uvm_status_e status;uvm_reg_data_t value;bit[31:0] counter;uvm_reg_block blks[$];reg_model p_rm;if(starting_phase != null) starting_phase.raise_objection(this);uvm_reg_block::get_root_blocks(blks);if(blks.size() == 0)`uvm_fatal("case0_cfg_vseq", "can't find root blocks")else beginif(!$cast(p_rm, blks[0]))`uvm_fatal("case0_cfg_vseq", "can't cast to reg_model")endp_rm.invert.read(status, value, UVM_FRONTDOOR);`uvm_info("case0_cfg_vseq", $sformatf("invert's initial value is %0h", value), UVM_LOW)p_rm.invert.write(status, 1, UVM_FRONTDOOR);p_rm.invert.read(status, value, UVM_FRONTDOOR);`uvm_info("case0_cfg_vseq", $sformatf("after set, invert's value is %0h", value), UVM_LOW)p_rm.counter.read(status, value, UVM_FRONTDOOR);counter = value;`uvm_info("case0_cfg_vseq", $sformatf("counter's initial value(FRONTDOOR) is %0h", counter), UVM_LOW)p_rm.counter.poke(status, 32'hFFFD);p_rm.counter.read(status, value, UVM_FRONTDOOR);counter = value;`uvm_info("case0_cfg_vseq", $sformatf("after poke, counter's value(FRONTDOOR) is %0h", counter), UVM_LOW)p_rm.counter.peek(status, value);counter = value;`uvm_info("case0_cfg_vseq", $sformatf("after poke, counter's value(BACKDOOR) is %0h", counter), UVM_LOW)if(starting_phase != null) starting_phase.drop_objection(this);endtaskendclassclass case0_vseq extends uvm_sequence;`uvm_object_utils(case0_vseq)`uvm_declare_p_sequencer(my_vsqr)function new(string name= "case0_vseq");super.new(name);endfunction virtual task body();case0_sequence dseq;uvm_status_e status;uvm_reg_data_t value;if(starting_phase != null) starting_phase.raise_objection(this);#10000;dseq = case0_sequence::type_id::create("dseq");dseq.start(p_sequencer.p_my_sqr);if(starting_phase != null) starting_phase.drop_objection(this);endtaskendclassclass my_case0 extends base_test;function new(string name = "my_case0", uvm_component parent = null);super.new(name,parent);endfunction extern virtual function void build_phase(uvm_phase phase); `uvm_component_utils(my_case0)
endclassfunction void my_case0::build_phase(uvm_phase phase);super.build_phase(phase);uvm_config_db#(uvm_object_wrapper)::set(this, "v_sqr.configure_phase", "default_sequence", case0_cfg_vseq::type_id::get());uvm_config_db#(uvm_object_wrapper)::set(this, "v_sqr.main_phase", "default_sequence", case0_vseq::type_id::get());
endfunction`endif
2.26 top_tb
`timescale 1ns/1ps
`include "uvm_macros.svh" //UVM中的一个文件,包含众多的宏定义import uvm_pkg::*; //将整个uvm_pkg导入到验证平台中,编译器在编译my_driver.sv文件时才能认识uvm_driver其中的uvm_driver等类名
`include "my_if.sv"
`include "bus_if.sv"
`include "bus_transaction.sv"
`include "bus_agent.sv"
`include "bus_driver.sv"
`include "bus_monitor.sv"
`include "bus_sequencer.sv"
`include "my_transaction_i.sv"
`include "my_transaction_o.sv"
`include "my_sequencer.sv"
`include "my_driver.sv"
`include "my_monitor_i.sv"
`include "my_monitor_o.sv"
`include "my_agent_i.sv"
`include "my_agent_o.sv"
`include "my_model.sv"
`include "my_scoreboard.sv"
`include "my_env.sv"
`include "base_test.sv"
`include "my_case0.sv"
`include "reg_model.sv"
`include "my_adapter.sv"
`include "my_vsqr.sv"module top_tb;reg clk;
reg rst_n;
reg [7:0] a;
reg [7:0] b;
reg enable;
reg cin;wire enable1;
wire cout;
wire [7:0] sum; my_if input_if(clk, rst_n);
my_if output_if(clk, rst_n);
bus_if b_if(clk,rst_n);dut my_dut(.clk(clk), //例化DUT.rst_n(rst_n),.a(input_if.a),.b(input_if.b),.cin(input_if.cin),.enable(input_if.enable),.enable1(output_if.enable1),.cout(output_if.cout),.sum(output_if.sum),.bus_cmd_valid (b_if.bus_cmd_valid),.bus_op (b_if.bus_op),.bus_addr (b_if.bus_addr),.bus_wr_data (b_if.bus_wr_data),.bus_rd_data (b_if.bus_rd_data));initial begin clk = 0;forever begin#100 clk = ~clk;end
endinitial beginrst_n = 1'b0;#1000;rst_n = 1'b1;
endinitial begin run_test();
endinitial begininput_if.a = 8'b00000000;input_if.b = 8'b00000000;input_if.cin = 1'b0;input_if.enable = 1'b1;
endinitial begin//(1) uvm_config_db::setuvm_config_db#(virtual my_if)::set(null, "uvm_test_top.env.i_agt.drv", "vif", input_if);uvm_config_db#(virtual my_if)::set(null, "uvm_test_top.env.i_agt.mon", "vif", input_if);uvm_config_db#(virtual my_if)::set(null, "uvm_test_top.env.o_agt.mon", "vif", output_if);uvm_config_db#(virtual bus_if)::set(null, "uvm_test_top.env.bus_agt.drv", "vif", bus_if);uvm_config_db#(virtual bus_if)::set(null, "uvm_test_top.env.bus_agt.mon", "vif", bus_if);
endendmodule
相关文章:
UVM实战--带有寄存器的加法器
一.整体的设计结构图 这里将DUT换成加法器,可以理解为之前UVM加法器加上寄存器,这里总线的功能不做修改,目的看代码的移植那些部分需要修改。 二.各个组件代码详解 2.1 DUT module dut( input clk, input rst_n, input…...
笔记--学习mini3d代码
主要是记录学习mini3d代码时,查的资料; 从github下载的代码: GitHub - skywind3000/mini3d: 3D Software Renderer in 700 Lines !!3D Software Renderer in 700 Lines !! Contribute to skywind3000/mini3d development by creating an a…...
图片服务器
文章目录一、项目简介二、功能及场景三、业务设计四、数据库设计准备图片表准备实体类五、API设计常用功能封装文件上传文件上传获取图片列表接口获取图片内容删除图片接口六、项目优化七、测试自动化测试测试用例一、项目简介 图片服务器:解决项目中插入图片的问题…...
【JAVA程序设计】【C00110】基于SSM(非maven)的车辆维修管理系统
基于SSM(非maven)的车辆维修管理系统项目简介项目获取开发环境项目技术运行截图项目简介 基于ssm框架非maven开发的车辆维修管理系统共分为三个角色:管理员、用户 管理员角色包含以下功能: 查看用户、添加用户、查看车辆信息、故…...
微积分小课堂:用动态的眼光去找问题的最优解(最大值/最小值)【中学里的解题技巧】
文章目录 引言I 最优化问题1.1 不同形式的最优化1.2 用动态的眼光去找问题的最优解引言 把比较数大小的问题,变成了寻找函数变化拐点的问题,将这两个问题等同起来,需要发明一种工具,叫做导数。有了导数这个工具,求最大值问题就变成了解方程的问题。 用变化的眼光找到最优…...
网络爬虫和相关工具
在理想的状态下,所有ICP(Internet Content Provider)都应该为自己的网站提供API接口来共享它们允许其他程序获取的数据,在这种情况下爬虫就不是必需品,国内比较有名的电商平台(如淘宝、京东等)、…...
OSSFs挂载工具简介
OSSFs挂载工具 OSSFs挂载工具简介 ossfs允许您在Linux系统中将对象存储OSS的存储空间(Bucket)挂载到本地文件系统。挂载完成后,您能够像操作本地文件一样操作OSS的对象(Object),从而实现数据共享。 …...
Spring 容器创建初始化,获取bean流程分析
Spring 容器创建初始化,获取bean流程分析 Spring 容器创建初始化 流程分析 1、首先读取bean.xml 文件 2、扫描指定的包 com.hspedu.spring.component 2.1、扫描包,得到bean的class对象,排除包下不是bean的 2.2、扫描将bean信息封装BeanDef…...
无聊小知识.03 Springboot starter配置自动提示
1、前言Springboot项目配置properties或yaml文件时候,会有很多spring相关的配置提示。这个是如何实现的?如果我们自己的配置属性,能否也自动提示?2、Springboot配置自动提示其实IDE是通过读取配置信息的元数据而实现自动提示的。S…...
2023-03-03 mysql-join类别-分析
目录 摘要: mysql版本: DDL: 表结构: 插入数据: JOIN: 一. SELECT 二. INNER JOIN...
Saleen 系列来袭!
由 Ghostopunch 创作👻🥊 Ghostpunch 将 Saleen Automotive 带入 The Sandbox 元宇宙! 是 Saleen Automotive 于 1984 年由汽车界的梦想家 Steve Saleen 创立,目标是将经过比赛验证的性能带入大街小巷和元宇宙……😉 5…...
如何优雅地处理Java中的null值?使用Optional类来实现!
当我们在Java编程时,经常会遇到处理null值的问题。在Java 8中,引入了一个Optional类来解决这个问题。Optional类可以看作是一个容器,用于包装一个可能为null的值。它提供了一些方便的方法,以优雅地处理null值的情况。 下面我将详…...
巾帼绽芬芳 一起向未来(中篇)
编者按:为了隆重纪念纪念“三八”国际妇女节113周年,快来与你全方位、多层次分享交流“三八”国际妇女节的前世今生。分上篇(节日简介、节日发展和节日意义)、中篇(节日活动宗旨和世界各国庆祝方式)和下篇&…...
espnet training
from:ESPnet2 — ESPnet 202301 documentation from :Change the configuration for training — ESPnet 202301 documentation 训练完之后微调的命令: ./run.sh --stage 11 --ngpu 1 --asr_args "--max_epoch 205 --optim_conf lr=0.1 --resume true" --asr_exp…...
qsort函数的应用以及模拟实现
前言 🎈个人主页:🎈 :✨✨✨初阶牛✨✨✨ 🐻推荐专栏: 🍔🍟🌯 c语言进阶 🔑个人信条: 🌵知行合一 🍉本篇简介:>:介绍库函数qsort函数的模拟实现和应用 金句分享: ✨追…...
【iobit 软件】家族系列 - 正版激活码
装机必备iobit系列软件 - 激活码获取看最后 第一款、Advanced SystemCare 16 您需要的人工智能驱动的PC优化器,以释放磁盘空间,加速PC并保护在线隐私。 功能特点: 1. 系统清理与优化:通过清除系统垃圾文件、注册表信息、无用文…...
ACM-大一训练第三周(Floyd算法+并查集算法专题训练)
🚀write in front🚀 📝个人主页:认真写博客的夏目浅石.CSDN 🎁欢迎各位→点赞👍 收藏⭐️ 留言📝 📣系列专栏:ACM周训练题目合集.CSDN 💬总结:…...
taobao.item.sku.update( 更新SKU信息 )
¥开放平台免费API必须用户授权 *更新一个sku的数据 *需要更新的sku通过属性properties进行匹配查找 *商品的数量和价格必须大于等于0 *sku记录会更新到指定的num_iid对应的商品中 *num_iid对应的商品必须属于当前的会话用户 公共参数 请求地址: HTTP地址 http://gw.…...
ros2创建一个工程
第一步:创建src目录 $ mkdir ros2-demo $ cd ros2-demo/ $ mkdir src $ cd src/第二步:创建功能包cd src$ ros2 pkg create --build-type ament_cmake ros2_demo --dependencies rclcpp std_msgsros2 pkg create --build-type ament_python learning_pkg…...
【力扣】stack容器的探索之有效的括号
作者:狮子也疯狂 专栏:《算法详解》 愿你生如夏花之绚烂,幸运永远与你相伴,疯狂常在。 目录一. 🦁 Stack容器的来历1.1 操作栈的方法二. 🦁 Stack的使用2.1 题目2.2 分析2.3 详细算法实现2.4 力扣AC截图三…...
【Elsevier出版社】中科院2区,SCIEEI 双检,已有发表案例,3个月左右录用
1区智能传感器类SCIE&EI 【期刊简介】IF:5.0-6.0,JCR1区,中科院2区,SCI&EI 双检,正刊 【参考周期】3个月左右录用 【截稿日期】2023.5.30 【征稿领域】有关人工智能与传感器的相关研究均可 包括但不限于&#…...
基于明道云平台重建医院管理流程
一、龙华区医疗信息化建设情况 首先,给大家介绍一下龙华区医疗信息化建设的情况,龙华区位于深圳市的中部,目前下属3家公立医院,2家公共卫生机构。2017年,龙华区提出了建设智慧龙华总体框架方案,龙华区卫生…...
【蓝桥杯嵌入式】STM32定时器的配置,解析预分频系数和重装载值与时钟频率的关系
🎊【蓝桥杯嵌入式】专题正在持续更新中,原理图解析✨,各模块分析✨以及历年真题讲解✨都在这儿哦,欢迎大家前往订阅本专题,获取更多详细信息哦🎏🎏🎏 🪔本系列专栏 - 蓝…...
ChatGPT API 低价上线,开发者可以人手一个了?
千呼万唤,ChatGPT API来了! 不仅首发,价格居然还有惊喜,0.002美元/每1000 token,并将价格降低90%,直接打了1折。OpenAI官方还表示,gpt-3.5-turbo目前的版本代号是gpt-3.5-turbo-0301࿰…...
品牌营销策略 | 科学经营合作伙伴关系的5个要素
在管理众多的合作伙伴项目时,企业会遇到很多的问题,比如,数据信息分散凌乱、手动操作繁琐重复和处理环节粗放等。这将耗费公司大量的人力物力,严重影响大数据的综合分析和利用。因此,企业要科学管理好企业的合作伙伴关…...
【剑指offer-C++】JZ20:表示数值的字符串
【剑指offer-C】JZ20:表示数值的字符串题目描述解题思路题目描述 描述:请实现一个函数用来判断字符串str是否表示数值(包括科学计数法的数字,小数和整数)。 科学计数法的数字(按顺序)可以分成以下几个部分…...
【NLP相关】深度学习领域不同编程IDE对比
❤️觉得内容不错的话,欢迎点赞收藏加关注😊😊😊,后续会继续输入更多优质内容❤️👉有问题欢迎大家加关注私戳或者评论(包括但不限于NLP算法相关,linux学习相关,读研读博…...
定制ubuntu的docker镜像
ssh登录jdkmavenvimpingcurlFROM ubuntu:22.04RUN apt-get updateRUN apt-get install -y \vim \inetutils-ping \openssh-server \curl \openjdk-8-jdk \mavenRUN mkdir /var/run/sshdRUN echo root:root |chpasswdRUN sed -ri s/^#?PermitRootLogin\s.*/PermitRootLogin yes…...
我的 System Verilog 学习记录(8)
引言 本文简单介绍 SystemVerilog 的接口。 前文链接: 我的 System Verilog 学习记录(1) 我的 System Verilog 学习记录(2) 我的 System Verilog 学习记录(3) 我的 System Verilog 学习记…...
详解JAVA字节码
目录 1.概述 2.字节码文件构成 2.1.魔数 2.2.版本号 2.3.常量池 2.4.访问标志 2.5.索引 2.6.字段表 2.7.方法表 3.字节码指令 3.1.概述 3.2.指令分类 3.2.1.加载存储指令 3.2.2.运算指令 3.2.3.其他指令 3.3.完整指令工作流程 4.字节码保护 1.概述 以往的编程…...
群晖ds1817做网站/谷歌浏览器 安卓下载2023版官网
在Megaupload被关闭,资产扣押和关键成员被逮捕之后,为避免同样的命运,另一些文件共享网站开始采取行动调整其服务。Filesonic已经关闭了文件共享功能。Filesonic的声明称,用户只能上传和下载个人使用文件。在移除文件共享功能前&a…...
网站应当实现那些功能 流程如何设计/品牌营销策略
数据库表中的数据都是存储在页里的,那么一个页可以存放多少条记录呢?这取决于一行记录的大小是多少,假如一行数据大小是1k,那么理论上一页就可以放16条数据。当然,查询数据的时候,MySQL也不能把所有的页都遍…...
b2b电子商务网站调研报告word文档形式/海外网站
extends可以理解为全盘继承了父类的功能implements可以理解为为这个类附加一些额外的功能举个例子,Animal是一个父类,cat,dog,bird,insect都extends了Animal,但是cat,dog,bird还可以…...
西安网站网站建设/营销策略的概念
今天,我们列出了10个jQuery灯箱插件,以使您的媒体在网站上优雅地显示而无需加载新窗口,图像和视频可以加载在叠加在当前页面上的弹出式窗口中。 宏伟的响应式弹出灯箱 1. piroBox 这是pirobox的高级版本,我比以前的版本实现了更…...
在哪个网站上可以找兼职做/网络广告策划的内容
6月29日,阿里巴巴研发效能部与PMI、Teambition联合举办的阿里巴巴研发效能实践日将在杭州西溪园区举行,活动聚焦敏捷精益项目管理。活动详情及报名可点我前往。 项目管理的目的是什么?面对工作中的各种不确定性,如何利用数据帮助项…...
福州app开发/网站关键字优化公司
项目需要做一个滚动显示长图片的功能,跟公司大牛请教后得知cocos有个控件叫scrollview,遂学习了一下,记录一些坑..... 上代码先: var cache cc.SpriteFrameCache.getInstance();cache.addSpriteFrames("img/c.plist");var img cc.SpriteFrameCache.getInstance()…...