当前位置: 首页 > news >正文

网站开发纠纷app优化推广

网站开发纠纷,app优化推广,企业员工培训内容及计划,网络销售有限公司在公司写代码的时候发现前辈有一段这样的代码: ....//其他transaction uvm_create(trans);........ uvm_send(trans); tmp_id trans.get_transaction_id(); get_response(rsp,tmp_id); 如果前面有其他transaction,这段代码里的get_response不带id的话…

在公司写代码的时候发现前辈有一段这样的代码:

....//其他transaction
`uvm_create(trans);........
`uvm_send(trans);
tmp_id = trans.get_transaction_id();
get_response(rsp,tmp_id);

如果前面有其他transaction,这段代码里的get_response不带id的话,就会错误地get到前面transaction的response,有点好奇原理,就去看了看源码。

先从driver入手,如果要返回response的话,要先new一个rsp,然后set_id_info,再put_response:

//参考张强白皮书
seq_item_port.get_next_item(req);
drive_one_pkt(req);
rsp = new("rsp");
rsp.set_id_info(req);
seq_item_port.put_response(rsp);
seq_item_port.item_done();

先看set_id_info这个函数,在uvm_sequence_item.svh里面,作用就是将req的两个id set到rsp里,我们主要关注transaction_id,继续往后走。

  function void set_id_info(uvm_sequence_item item);if (item == null) beginuvm_report_fatal(get_full_name(), "set_id_info called with null parameter", UVM_NONE);endthis.set_transaction_id(item.get_transaction_id());this.set_sequence_id(item.get_sequence_id());endfunction

get_transaction_id在uvm_transaction.svh里面,返回了m_transaction_id,这个id是uvm_transaction里面的一个local integer变量,默认值为-1。这个id的更改在其他地方,稍后再讲解。

function void uvm_transaction::set_transaction_id(integer id);m_transaction_id = id;
endfunctionfunction integer uvm_transaction::get_transaction_id();return (m_transaction_id);
endfunction

然后看put_response函数,在uvm_sequence.svh里,调用了put_base_response函数。

  virtual function void put_response(uvm_sequence_item response_item);RSP response;if (!$cast(response, response_item)) beginuvm_report_fatal("PUTRSP", "Failure to cast response in put_response", UVM_NONE);endput_base_response(response_item);endfunction

put_base_response在uvm_sequence_base.svh里,作用是将response压入队列中,队列默认长度为8,即response_queue_depth=8,当response在队列中的数量为8还继续压入队列后就会报错,一般发生在没有取response的情况下。

  virtual function void put_base_response(input uvm_sequence_item response);if ((response_queue_depth == -1) ||(response_queue.size() < response_queue_depth)) beginresponse_queue.push_back(response);return;endif (response_queue_error_report_disabled == 0) beginuvm_report_error(get_full_name(), "Response queue overflow, response was dropped", UVM_NONE);endendfunction

接下来到sequence端,我们看看transaction的id和response是怎么get的。transaction_id,在uvm_transaction.svh里,就是返回m_transaction_id。get_response在uvm_sequence.svh里,调用了get_base_response,这里的参数列表里就有transaction_id了

  virtual task get_response(output RSP response, input int transaction_id = -1);uvm_sequence_item rsp;get_base_response( rsp, transaction_id);$cast(response,rsp);endtask

get_base_response在uvm_sequence_base.svh里,可以看到在没有指定transaction_id(id为默认值)的时候,返回的response是从队列直接pop的,指定了以后就遍历队列找id对应的response,这里就是最前面代码的机制。

  virtual task get_base_response(output uvm_sequence_item response, input int transaction_id = -1);int queue_size, i;if (response_queue.size() == 0)wait (response_queue.size() != 0);if (transaction_id == -1) beginresponse = response_queue.pop_front();return;endforever beginqueue_size = response_queue.size();for (i = 0; i < queue_size; i++) beginif (response_queue[i].get_transaction_id() == transaction_id) begin$cast(response,response_queue[i]);response_queue.delete(i);return;endendwait (response_queue.size() != queue_size);endendtask

但是到目前为止,response阶段没有看到id是怎么来的,我们从transaction的create和send阶段找一下。这些宏在uvm_sequence_defines.svh里,可以看到create阶段不涉及id的操作,send里面调了函数,可能会有。因为我们send的是transaction,是uvm_sequence_item类型,uvm_sequence_base是其子类,所以在uvm_send_pri里case不会成功,首先进入start_item里。

`define uvm_create(SEQ_OR_ITEM) \`uvm_create_on(SEQ_OR_ITEM, m_sequencer)`define uvm_create_on(SEQ_OR_ITEM, SEQR) \begin \uvm_object_wrapper w_; \w_ = SEQ_OR_ITEM.get_type(); \$cast(SEQ_OR_ITEM , create_item(w_, SEQR, `"SEQ_OR_ITEM`"));\end`define uvm_send(SEQ_OR_ITEM) \`uvm_send_pri(SEQ_OR_ITEM, -1)`define uvm_send_pri(SEQ_OR_ITEM, PRIORITY) \begin \uvm_sequence_base __seq; \if (!$cast(__seq,SEQ_OR_ITEM)) begin \start_item(SEQ_OR_ITEM, PRIORITY);\finish_item(SEQ_OR_ITEM, PRIORITY);\end \else __seq.start(__seq.get_sequencer(), this, PRIORITY, 0);\end

start_item在uvm_sequence_base.svh里,貌似也不涉及id的操作,再看finish_item,也在vm_sequence_base.svh里。finish_item调用了sequencer的send_request函数,进去看看。

 virtual task start_item (uvm_sequence_item item,int set_priority = -1,uvm_sequencer_base sequencer=null);uvm_sequence_base seq;if(item == null) beginuvm_report_fatal("NULLITM",{"attempting to start a null item from sequence '",get_full_name(), "'"}, UVM_NONE);return;endif($cast(seq, item)) beginuvm_report_fatal("SEQNOTITM",{"attempting to start a sequence using start_item() from sequence '",get_full_name(), "'. Use seq.start() instead."}, UVM_NONE);return;endif (sequencer == null)sequencer = item.get_sequencer();if(sequencer == null)sequencer = get_sequencer();   if(sequencer == null) beginuvm_report_fatal("SEQ",{"neither the item's sequencer nor dedicated sequencer has been supplied to start item in ",get_full_name()},UVM_NONE);return;enditem.set_item_context(this, sequencer);if (set_priority < 0)set_priority = get_priority();sequencer.wait_for_grant(this, set_priority);`ifndef UVM_DISABLE_AUTO_ITEM_RECORDINGvoid'(sequencer.begin_child_tr(item, m_tr_handle, item.get_root_sequence_name()));`endifpre_do(1);endtask  virtual task finish_item (uvm_sequence_item item,int set_priority = -1);uvm_sequencer_base sequencer;sequencer = item.get_sequencer();if (sequencer == null) beginuvm_report_fatal("STRITM", "sequence_item has null sequencer", UVM_NONE);endmid_do(item);sequencer.send_request(this, item);sequencer.wait_for_item_done(this, -1);`ifndef UVM_DISABLE_AUTO_ITEM_RECORDINGsequencer.end_tr(item);`endifpost_do(item);endtask

send_request在uvm_sequencer_param_base里,可以看到req的transaction_id就是在这里设置的,值为m_next_transaction_id,且每次设置完就自加1,这个值在uvm_sequence_base.svh里,初值为1。

function void uvm_sequencer_param_base::send_request(uvm_sequence_base sequence_ptr,uvm_sequence_item t,bit rerandomize = 0);REQ param_t;if (sequence_ptr == null) beginuvm_report_fatal("SNDREQ", "Send request sequence_ptr is null", UVM_NONE);endif (sequence_ptr.m_wait_for_grant_semaphore < 1) beginuvm_report_fatal("SNDREQ", "Send request called without wait_for_grant", UVM_NONE);endsequence_ptr.m_wait_for_grant_semaphore--;if ($cast(param_t, t)) beginif (rerandomize == 1) beginif (!param_t.randomize()) beginuvm_report_warning("SQRSNDREQ", "Failed to rerandomize sequence item in send_request");endendif (param_t.get_transaction_id() == -1) beginparam_t.set_transaction_id(sequence_ptr.m_next_transaction_id++);endm_last_req_push_front(param_t);end else beginuvm_report_fatal(get_name(),$sformatf("send_request failed to cast sequence item"), UVM_NONE);endparam_t.set_sequence_id(sequence_ptr.m_get_sqr_sequence_id(m_sequencer_id, 1));t.set_sequencer(this);if (m_req_fifo.try_put(param_t) != 1) beginuvm_report_fatal(get_full_name(), "Concurrent calls to get_next_item() not supported. Consider using a semaphore to ensure that concurrent processes take turns in the driver", UVM_NONE);endm_num_reqs_sent++;// Grant any locks as soon as possiblegrant_queued_locks();
endfunction

这下搞清楚了,transaction_id初值为1,且一个sequence里面每个transaction_id的值均不相同,每发一个req,id都会加一,通过这个id可以来区分不同的transaction!

http://www.hkea.cn/news/985835/

相关文章:

  • 适合站长做的网站信息流广告投放工作内容
  • 做健身网站步骤网站建设网络公司
  • 武汉整站seo数据上云网站关键词优化怎么做的
  • 网站尾部网络seo推广
  • 建设一个公司网站需要什么知识网站网络推广优化
  • 政府高度重视网站建设怎么做网络推广
  • 自己做的网站是怎么赚钱免费ip地址网站
  • 郑州市政府网站集约化建设计划企业seo排名外包
  • 什么网站可以免费做护师题企业网站管理系统源码
  • 青岛专业餐饮网站制作国内搜索引擎排行榜
  • 域名有哪些seo站长之家
  • 建设网站有哪些关键词制作软件
  • 视频网站怎么制作网店推广的作用是什么
  • 网站栏目怎么做单独的搜索框云南疫情最新消息
  • 独立商城b2c电商网站开发合肥百度seo代理
  • 做购物网站需不需要交税费郑州网站托管
  • 是不是做网站就能赚钱谷歌seo关键词优化
  • 萝岗门户网站建设今日重大新闻头条财经
  • 个人相册网站模板怎么把网站排名排上去
  • 建设外贸网站案例统计站老站长推荐草莓
  • 1688网站的特点全网营销系统
  • 西安做网站企业网址怎么申请
  • 专业网站建设品牌百度指数里的资讯指数是什么
  • 做网站规避什么网站制作
  • 网站开发工作方案2022拉人头最暴利的app
  • 网站建设好还是阿里巴巴好磁力猫torrent kitty
  • wordpress跨域访问前端优化网站
  • 住房和城乡建设部网站买卖合同北京中文seo
  • WordPress自己安装了插件深圳seo推广外包
  • 建立网站舆情分析报告范文