I2C学习笔记——00apb_mst侧trans、drv、mon、sqr、agt

news/2024/12/2 6:31:14/

操作VCS:make elab  、 make run GUI=1 TEST=___________ &

        questasim:pwd当前路径  、 cd到sim目录下、  do rkv_i2c_sim.do进行编译和仿真

APB master侧:

   apb_transfer:   extends uvm_sequence_item;

        两个自定义枚举:表示读写 apb_trans_kind、表示OKERROR状态apb_trans_status;

        定义随机32位addr、32位data、trans_kind、trans_status、软约束为1的idle_cycles;

        注册 域的自动化;

`ifndef LVC_APB_TRANSFER_SV
`define LVC_APB_TRANSFER_SV//------------------------------------------------------------------------------
//
// transfer enums, parameters, and events
//
//------------------------------------------------------------------------------
typedef enum {IDLE, WRITE, READ } lvc_apb_trans_kind;
typedef enum {OK, ERROR} lvc_apb_trans_status;//------------------------------------------------------------------------------
//
// CLASS: lvc_apb_transfer
//
//------------------------------------------------------------------------------class lvc_apb_transfer extends uvm_sequence_item;// USER: Add transaction fieldsrand bit [31:0]      addr;rand bit [31:0]      data;rand lvc_apb_trans_kind  trans_kind; rand lvc_apb_trans_status trans_status;rand int idle_cycles;constraint cstr{soft idle_cycles == 1;};// USER: Add constraint blocks`uvm_object_utils_begin(lvc_apb_transfer)`uvm_field_enum     (lvc_apb_trans_kind, trans_kind, UVM_ALL_ON)// USER: Register fields here`uvm_field_int      (addr, UVM_ALL_ON)`uvm_field_int      (data, UVM_ALL_ON)`uvm_field_int      (idle_cycles, UVM_ALL_ON)`uvm_object_utils_end// new - constructorfunction new (string name = "lvc_apb_transfer_inst");super.new(name);endfunction : newendclass : lvc_apb_transfer`endif // LVC_APB_TRANSFER_SV

apb_master_driver.svh头文件:参数化类extends uvm_driver #(lvc_apb_transfer);

        例化config;注册;virtual vif;

       声明函数new (string name, uvm_component parent); 任务run()、get_and_drive()、drive_transfer(lvc_apb_transfer t)、reset_listener()、do_idle()、do_write(lvc_apb_transfer t)、do_read(lvc_apb_transfer t);

`ifndef LVC_APB_MASTER_DRIVER_SVH
`define LVC_APB_MASTER_DRIVER_SVHclass lvc_apb_master_driver extends uvm_driver #(lvc_apb_transfer);//////  Public interface (Component users may manipulate these fields/methods)////lvc_apb_config cfg;// USER: Add your fields here// This macro performs UVM object creation, type control manipulation, and // factory registration`uvm_component_utils_begin(lvc_apb_master_driver)// USER: Register fields here`uvm_component_utils_end// new - constructorextern function new (string name, uvm_component parent);// uvm run phaseextern virtual task run();//////  Implementation (private) interface////// The virtual interface used to drive and view HDL signals.virtual lvc_apb_if vif;// This is the method that is responsible for getting sequence transactions// and driving the transaction into the DUTextern virtual protected task get_and_drive();// This method drives a sequence trasnaction onto the interfaceextern virtual protected task drive_transfer(lvc_apb_transfer t);// This method reset interface signalsextern virtual protected task reset_listener();// This method that is responsible for sending an idle cycle to the DUTextern protected task do_idle();// This method that is to trigger write transactionextern protected task do_write(lvc_apb_transfer t);// This method that is to trigger read transactionextern protected task do_read(lvc_apb_transfer t);endclass : lvc_apb_master_driver`endif // LVC_APB_MASTER_DRIVER_SVH

apb_master_driver.sv:

        实现头文件中各函数任务;run()→get_and_drive()→get_next_item、drive_transfer(req)中判断trans_kind读写(如下),克隆、id、itemdone→reset_listener()

        写do_write(t):第一拍给paddr、pwrite=1、psel=1、penable=0,t.data给pwdata;第二拍penable=1传输数据;10ps后等待接口上pready等于1后,1ps判断接口上pslverr如果为1,状态转为ERROR,不为1转为OK;

        读do_read(t):第一拍给paddr、pwrite=0、psel=1、penable=0;第二拍penable=1传输数据;10ps后等待接口上pready等于1后,1ps判断接口上pslverr如果为1,状态转为ERROR,不为1转为OK;并将vif上prdata给t.data;

`ifndef LVC_APB_MASTER_DRIVER_SV
`define LVC_APB_MASTER_DRIVER_SVfunction lvc_apb_master_driver::new (string name, uvm_component parent);super.new(name, parent);
endfunction : newtask lvc_apb_master_driver::run();forkget_and_drive();reset_listener();join_none
endtask : runtask lvc_apb_master_driver::get_and_drive();forever beginseq_item_port.get_next_item(req);`uvm_info(get_type_name(), "sequencer got next item", UVM_HIGH)drive_transfer(req);void'($cast(rsp, req.clone()));rsp.set_sequence_id(req.get_sequence_id());rsp.set_transaction_id(req.get_transaction_id());seq_item_port.item_done(rsp);`uvm_info(get_type_name(), "sequencer item_done_triggered", UVM_HIGH)end
endtask : get_and_drivetask lvc_apb_master_driver::drive_transfer (lvc_apb_transfer t);`uvm_info(get_type_name(), "drive_transfer", UVM_HIGH)case(t.trans_kind)IDLE    : this.do_idle();WRITE   : this.do_write(t);READ    : this.do_read(t);default : `uvm_error("ERRTYPE", "unrecognized transaction type")endcase
endtask : drive_transfertask lvc_apb_master_driver::do_write(lvc_apb_transfer t);`uvm_info(get_type_name(), "do_write ...", UVM_HIGH)@(vif.cb_mst);vif.cb_mst.paddr <= t.addr;vif.cb_mst.pwrite <= 1;vif.cb_mst.psel <= 1;vif.cb_mst.penable <= 0;vif.cb_mst.pwdata <= t.data;@(vif.cb_mst);vif.cb_mst.penable <= 1;#10ps;wait(vif.pready === 1);#1ps;if(vif.pslverr === 1) begint.trans_status = ERROR;if(cfg.master_pslverr_status_severity ==  UVM_ERROR)`uvm_error(get_type_name(), "PSLVERR asserted!")else`uvm_warning(get_type_name(), "PSLVERR asserted!")endelse begint.trans_status = OK;endrepeat(t.idle_cycles) this.do_idle();
endtask: do_writetask lvc_apb_master_driver::do_read(lvc_apb_transfer t);`uvm_info(get_type_name(), "do_write ...", UVM_HIGH)@(vif.cb_mst);vif.cb_mst.paddr <= t.addr;vif.cb_mst.pwrite <= 0;vif.cb_mst.psel <= 1;vif.cb_mst.penable <= 0;@(vif.cb_mst);vif.cb_mst.penable <= 1;#10ps;wait(vif.pready === 1);#1ps;if(vif.pslverr === 1) begint.trans_status = ERROR;if(cfg.master_pslverr_status_severity ==  UVM_ERROR)`uvm_error(get_type_name(), "PSLVERR asserted!")else`uvm_warning(get_type_name(), "PSLVERR asserted!")endelse begint.trans_status = OK;endt.data = vif.prdata;repeat(t.idle_cycles) this.do_idle();
endtask: do_readtask lvc_apb_master_driver::do_idle();`uvm_info(get_type_name(), "do_idle ...", UVM_HIGH)@(vif.cb_mst);vif.cb_mst.psel <= 0;vif.cb_mst.penable <= 0;vif.cb_mst.pwdata <= 0;
endtask:do_idletask lvc_apb_master_driver::reset_listener();`uvm_info(get_type_name(), "reset_listener ...", UVM_HIGH)forkforever begin@(negedge vif.rstn); // ASYNC resetvif.paddr <= 0;vif.pwrite <= 0;vif.psel <= 0;vif.penable <= 0;vif.pwdata <= 0;endjoin_none
endtask`endif // LVC_APB_MASTER_DRIVER_SV

apb_master_monitor.svh头文件:extends uvm_monitor;

        例化config;virtual vif;item_collected_port;定义两个变量checks_enable(控制是否检查)、coverage_enable(控制是否更新覆盖率)默认打开;注册,两个变量域的自动化;

`ifndef LVC_APB_MASTER_MONITOR_SVH
`define LVC_APB_MASTER_MONITOR_SVHclass lvc_apb_master_monitor extends uvm_monitor;//////  Public interface (Component users may manipulate these fields/methods)////lvc_apb_config cfg;// This field controls if this monitor has its checkers enabled// (by default checkers are on)bit checks_enable = 1;// This field controls if this monitor has its coverage enabled// (by default coverage is on)bit coverage_enable = 1;// This property is the virtual interface needed for this component to drive// and view HDL signalsvirtual lvc_apb_if vif;// USER: Add your fields here// The following is the analysis port that allows this monitor's transaction// information to be sent to other verification componets such as// scoreboardsuvm_analysis_port #(lvc_apb_transfer) item_collected_port;// This macro performs UVM object creation, type control manipulation, and // factory registration`uvm_component_utils_begin(lvc_apb_master_monitor)`uvm_field_int(checks_enable, UVM_ALL_ON)`uvm_field_int(coverage_enable, UVM_ALL_ON)// USER: Register fields here`uvm_component_utils_end// new - constructor     extern function new(string name, uvm_component parent=null);// uvm run phaseextern virtual task run();// Events needed to trigger covergroupsevent lvc_apb_master_cov_transaction;// Transfer collected covergroupcovergroup lvc_apb_master_cov_trans @lvc_apb_master_cov_transaction;// USER implemented coverpointsendgroup : lvc_apb_master_cov_trans//////  Implementation (private) interface//////This is the transaction being collected by this monitor	protected lvc_apb_transfer trans_collected;// This method is responsible for collecting transactions, checking,// and updating coverage extern virtual protected task monitor_transactions();// This is the methods that collects transactionsextern virtual protected task collect_transfer();// This is the method that performs checks on a transactionextern protected function void perform_transfer_checks();// This is the method that updates coverage based on a transactionextern protected function void perform_transfer_coverage();endclass : lvc_apb_master_monitor`endif // LVC_APB_MASTER_MONITOR_SVH

apb_master_monitor.sv:

        实现头文件中各函数任务:new item_collected_port;run()→monitor_transactions()→collect_transfer()中在cb_mon时钟上升沿等psel=1penable=0时,工厂创建一个trans_collected后,判断读写(如下)→perform_transfer_checks(目前没用)→perform_transfer_coverage(目前没用);

        写操作:等一上升沿并且接口上pready=1(说明写操作成功传输、mon需要监测);接口上传输paddr、pwdataWRITE、OKERROR状态到trans_collected;

        读操作:等一上升沿并且接口上pready=1(说明读操作成功传输、mon需要监测);接口上传输paddr、prdataREAD、OKERROR状态到trans_collected;

`ifndef LVC_APB_MASTER_MONITOR_SV
`define LVC_APB_MASTER_MONITOR_SVfunction lvc_apb_master_monitor::new(string name, uvm_component parent=null);super.new(name, parent);item_collected_port = new("item_collected_port",this);
endfunction:newtask lvc_apb_master_monitor::monitor_transactions();forever begin// Extract data from interface into transactioncollect_transfer();// Check transactionif (checks_enable)perform_transfer_checks();// Update coverageif (coverage_enable)perform_transfer_coverage();// Publish to subscribersitem_collected_port.write(trans_collected);end
endtask // monitor_transactionstask lvc_apb_master_monitor::run();forkmonitor_transactions();join_none
endtask // runtask lvc_apb_master_monitor::collect_transfer();// Advance clock@(vif.cb_mon iff (vif.cb_mon.psel === 1'b1 && vif.cb_mon.penable === 1'b0));trans_collected = lvc_apb_transfer::type_id::create("trans_collected");case(vif.cb_mon.pwrite)1'b1    : begin@(vif.cb_mon iff vif.cb_mon.pready === 1'b1);trans_collected.addr = vif.cb_mon.paddr;trans_collected.data = vif.cb_mon.pwdata;trans_collected.trans_kind = WRITE;trans_collected.trans_status = vif.cb_mon.pslverr === 1'b0 ? OK : ERROR;end 1'b0    : begin@(vif.cb_mon iff vif.cb_mon.pready === 1'b1);trans_collected.addr = vif.cb_mon.paddr;trans_collected.data = vif.cb_mon.prdata;trans_collected.trans_kind = READ;trans_collected.trans_status = vif.cb_mon.pslverr === 1'b0 ? OK : ERROR;enddefault : `uvm_error(get_type_name(), "ERROR pwrite signal value")endcase
endtask: collect_transfer // perform_transfer_checks
function void lvc_apb_master_monitor::perform_transfer_checks();// USER: do some checks on the transfer hereendfunction : perform_transfer_checks// perform_transfer_coverage
function void lvc_apb_master_monitor::perform_transfer_coverage();// USER: coverage implementation-> lvc_apb_master_cov_transaction;	endfunction : perform_transfer_coverage`endif // LVC_APB_MASTER_MONITOR_SV

apb_master_sequencer.svh头文件:参数类 extends uvm_sequencer #(lvc_apb_transfer);

        例化config;注册;virtual vif; 声明new();

`ifndef LVC_APB_MASTER_SEQUENCER_SVH
`define LVC_APB_MASTER_SEQUENCER_SVHclass lvc_apb_master_sequencer extends uvm_sequencer #(lvc_apb_transfer);//////  Public interface (Component users may manipulate these fields/methods)////lvc_apb_config cfg;// Provide implementations of virtual methods such as get_type_name and create`uvm_component_utils_begin(lvc_apb_master_sequencer)// USER: Register fields `uvm_component_utils_end// new - constructorextern function new (string name, uvm_component parent);//////  Implementation (private) interface////// The virtual interface used to drive and view HDL signals.virtual lvc_apb_if vif;endclass : lvc_apb_master_sequencer`endif // LVC_APB_MASTER_SEQUENCER_SVH

apb_master_sequencer.sv: 实现new

`ifndef LVC_APB_MASTER_SEQUENCER_SV
`define LVC_APB_MASTER_SEQUENCER_SVfunction lvc_apb_master_sequencer::new (string name, uvm_component parent);super.new(name, parent);
endfunction : new`endif // LVC_APB_MASTER_SEQUENCER_SV

apb_master_agent.svh头文件:extends uvm_agent;

例化config;例化drv、sqr、mon;注册;virtual vif;

声明函数new()、build()、connect()、assign_vi(分配virtual vif);

`ifndef LVC_APB_MASTER_AGENT_SVH
`define LVC_APB_MASTER_AGENT_SVHclass lvc_apb_master_agent extends uvm_agent;//////  Public interface (Component users may manipulate these fields/methods)////lvc_apb_config cfg;// The following are the verification components that make up// this agentlvc_apb_master_driver driver;lvc_apb_master_sequencer sequencer;lvc_apb_master_monitor monitor;virtual lvc_apb_if vif;// USER: Add your fields here// This macro performs UVM object creation, type control manipulation, and // factory registration`uvm_component_utils_begin(lvc_apb_master_agent)// USER: Register your fields here`uvm_component_utils_end// new - constructorextern function new (string name, uvm_component parent);// uvm build phaseextern function void build();// uvm connection phaseextern function void connect();// This method assigns the virtual interfaces to the agent's childrenextern function void assign_vi(virtual lvc_apb_if vif);//////  Implementation (private) interface////endclass : lvc_apb_master_agent`endif // LVC_APB_MASTER_AGENT_SVH

apb_master_agent.sv:new();

        build()中get config、virtual vif 并 工厂创建mon、cfg传递给mon;判断cfg中is_active是否为1,创建seq、drv并传递cfg;

        connect()中调用assign_vi函数传递vif;判断is_active为1,将drv port和seq export连接;

        assign_vi函数,vif连接mon的vif;判断is_active为1,vif连接seq和drv的vif;

`ifndef LVC_APB_MASTER_AGENT_SV
`define LVC_APB_MASTER_AGENT_SVfunction lvc_apb_master_agent::new(string name, uvm_component parent);super.new(name, parent);
endfunction : newfunction void lvc_apb_master_agent::build();super.build();// get configif( !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 interfaceif( !uvm_config_db#(virtual lvc_apb_if)::get(this,"","vif", vif)) begin`uvm_fatal("GETVIF","cannot get vif handle from config DB")endmonitor = lvc_apb_master_monitor::type_id::create("monitor",this);monitor.cfg = cfg;if(cfg.is_active == UVM_ACTIVE) beginsequencer = 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 : buildfunction void lvc_apb_master_agent::connect();assign_vi(vif);if(is_active == UVM_ACTIVE) begindriver.seq_item_port.connect(sequencer.seq_item_export);       endendfunction : connectfunction void lvc_apb_master_agent::assign_vi(virtual lvc_apb_if vif);monitor.vif = vif;if (is_active == UVM_ACTIVE) beginsequencer.vif = vif; driver.vif = vif; end
endfunction : assign_vi`endif // LVC_APB_MASTER_AGENT_SV


http://www.ppmy.cn/news/212023.html

相关文章

锐捷交换机和思科交换机差别

如果交换机已经有配置文件&#xff0c;你可以用setup命令初始化它。 模式&#xff1a;特权模式。 配置命令&#xff1a; Switch# setup 此时就会重复上面的步骤&#xff0c;配置交换机的初始参数。 注意&#xff1a;setup命令生成的配置文件会覆盖原有配置文件&#xff0c;所…

工业交换机有哪些厂家?

工业交换机的生产厂家有很多&#xff0c;现阶段中国行业竞争十分大。在普天信科来看这也是个好事情&#xff0c;由于这代表着進口网络交换机的销售市场在慢慢被稀释液&#xff0c;工业交换机逐渐国内生产制造的。并且工业交换机国内生产制造的拥有当地优点&#xff0c;价钱确实…

计算机网络中常见的交换机和路由器的品牌

H3C 华三&#xff08;由华为和美国的3COM公司合资&#xff0c;总部在杭州&#xff09;Cisco 思科&#xff08;总部在美国&#xff09;HUAWEI 华为&#xff08;总部在深圳&#xff09;锐捷&#xff08;总部在福建&#xff09;小米&#xff08;总部在北京&#xff09;360&#xf…

飞畅科技-国内老牌工业以太网交换机品牌

现如今&#xff0c;随着中国制造2025和工业4.0的逐渐展开&#xff0c;工业交换机的市场越来越大&#xff0c;尤其是在电力&#xff0c;交通&#xff0c;及工业自动化行业&#xff0c;但是进口品牌的在国内的份额却在不断的萎缩&#xff0c;这就给国内的很多工业交换机厂家一个非…

剑指 Offer 48. 最长不含重复字符的子字符串

题目&#xff1a; 请从字符串中找出一个最长的不包含重复字符的子字符串&#xff0c;计算该最长子字符串的长度。 示例 1: 输入: “abcabcbb” 输出: 3 解释: 因为无重复字符的最长子串是 “abc”&#xff0c;所以其长度为 3。 示例 2: 输入: “bbbbb” 输出: 1 解释: 因为无重…

家用、商用、工业交换机的用途与区别

以太网交换机一般分为&#xff1a;商用(以太网)交换机、工业(以太网)交换机、家用(以太网)交换机。那么&#xff0c;家用交换机&#xff0c;商业交换机&#xff0c;工业交换机之间有什么区别呢&#xff1f;接下来我们就跟随飞畅科技的小编一起来详细了解下吧&#xff01; 商用…

工业交换机和商用交换机对比

工业交换机是为了满足工业应用需求而专门设计的交换机&#xff0c;因为工业环境较为恶劣&#xff0c;且需要的性能也要比一般的交换机高。所以工业交换机要比商用交换机要的性能要稳定&#xff0c;需要耐受严苛的工作环境。工业交换机产品采用宽温设计&#xff0c;防护等级不低…

【owt】WebrtcNode, subscribe-sdp offer 流程(1)

sdp offer 流程 1. AmqpClient - New message received sdp offer 的消息 2023-04-26T21:54:19.790 - DEBUG: AmqpClient - RpcServer New message received {method: onTransportSignaling,args: [b149e44bb10d4e91bd162a8c6806ae7b,{sdp: v0\r\n o- 7177131362423164715 …