function void lvc_apb_master_agent::build(); super.build(); // get top config(agent work mode/apb bus signal(pready,pslverr)) if( !uvm_config_db#(lvc_apb_config)::get(this,"","cfg", cfg)) begin `uvm_warning("GETCFG","cannot get config object from config DB") cfg = lvc_apb_config::type_id::create("cfg"); end // get virtual interface(drive and monitor the signal of apb bus) if( !uvm_config_db#(virtual lvc_apb_if)::get(this,"","vif", vif)) begin `uvm_fatal("GETVIF","cannot get vif handle from config DB") end monitor = lvc_apb_master_monitor::type_id::create("monitor",this); monitor.cfg = cfg; //judge the cfg mode if(cfg.is_active == UVM_ACTIVE) begin sequencer = lvc_apb_master_sequencer::type_id::create("sequencer",this); sequencer.cfg = cfg; driver = lvc_apb_master_driver::type_id::create("driver",this); driver.cfg = cfg; end endfunction : build
时间: 2024-03-07 19:51:06 浏览: 95
这是一个 SystemVerilog 函数,用于构建一个 APB 总线的代理(agent)。它首先调用父类的 build 函数,然后从配置数据库(config DB)中获取代理的工作模式和 APB 总线信号的配置。如果无法获取配置对象,则创建一个新的配置对象。接着,它从配置数据库中获取代理所使用的虚拟接口(virtual interface)的句柄。如果无法获取虚拟接口的句柄,则会产生致命错误。然后,它创建一个 APB 总线的监控器(monitor)对象,并将配置对象传递给它。如果代理的工作模式为活动模式(UVM_ACTIVE),则创建一个 APB 总线的顺序器(sequencer)对象和一个 APB 总线的驱动器(driver)对象,并将配置对象传递给它们。最后,函数结束。
相关问题
virtual function void write_apb_master(lvc_apb_transfer tr); uvm_reg r; if(enable) begin r = cfg.rgm.default_map.get_reg_by_offset(tr.addr); if(r.get_name() == "IC_DATA_CMD" && ( (tr.trans_kind == lvc_apb_pkg::WRITE && cfg.rgm.IC_DATA_CMD_CMD.get() == RGM_WRITE && cfg.rgm.IC_STATUS_TFNF.get()) || (tr.trans_kind == lvc_apb_pkg::READ && cfg.rgm.IC_DATA_CMD_CMD.get() == RGM_READ && cfg.rgm.IC_STATUS_RFNE.get()) ) ) apb_trans_observed.push_back(tr); end endfunction: write_apb_master
这是一个虚拟函数,用于写入APB主机端口的数据。该函数接受一个名为tr的lvc_apb_transfer类型的参数,表示APB主机端口上的一次传输操作。其中包含了地址、数据、读写类型等信息。
函数首先通过地址查找对应的寄存器对象r。然后,判断寄存器对象r是否为"IC_DATA_CMD",并且判断读写类型和FIFO状态是否符合要求。如果符合要求,则将该次传输操作tr添加到名为apb_trans_observed的动态数组中。
这段代码通常用于在UVM测试中模拟APB总线的读写操作,并记录实际观测到的传输信息,以便后续的比较和验证。需要注意的是,该函数的执行前提是enable为真。
task i2c_refmod(); lvc_apb_transfer tr; ral_reg_rkv_i2c_IC_DATA_CMD data_cmd_r; bit[7:0] data; data_cmd_r = new("data_cmd_r"); data_cmd_r.build(); forever begin wait(apb_trans_observed.size() > 0) tr = apb_trans_observed.pop_front(); data_cmd_r.set(tr.data); if(tr.trans_kind == lvc_apb_pkg::WRITE && cfg.rgm.IC_DATA_CMD_CMD.get() == RGM_WRITE) begin write_data_expected.push_back(data_cmd_r.DAT.get()); write_count_expected++; end else if(tr.trans_kind == lvc_apb_pkg::READ && cfg.rgm.IC_DATA_CMD_CMD.get() == RGM_READ) begin read_data_expected.push_back(data_cmd_r.DAT.get()); read_count_expected++; end end endtask
这段代码看起来像是在实现 I2C 总线上的数据读写操作,其中使用了 lvc_apb_transfer 类型的变量 tr 来存储 APB 总线的传输信息,使用 ral_reg_rkv_i2c_IC_DATA_CMD 类型的变量 data_cmd_r 来存储 I2C 数据和命令信息,并且通过调用 data_cmd_r.set() 方法将 tr.data 赋值给 data_cmd_r 中的数据字段。然后根据传输的类型和命令类型来判断是读操作还是写操作,并将预期的数据存储到相应的队列中。其中,数据读写的具体实现可能需要在其他部分的代码中。
阅读全文