资讯动态

一些比较好的组件代码

发布时间:2026/9/10 1:03:48 来源:尧图企业网站定制
vld和rdy握手类型的驱动背景驱动收到rdy才能发起驱动否则保持。实践示例这样可以实现背对背发包需要注意的地方就是如果是最后一个包DUT rdy一直拉高TB这里发完最后一个包要接口的vld信号置为无效。否则vldrdy都会一直为高输入大量非预期的包。所以需要在发完一个item后再去初始化一下接口。task drv dut.data Tb.data; do begin clk //要和信号驱动时钟块保持一致不然会异步 end whilerdy 1 endtask task run_phase supper.phase; forever begin init_if(); ....;//get item drv(); end网上其他示例Simple ready-valid interface examples, data is sent in a loop - SystemVerilog - Verification Academy这里用了wait可能会潜在风险之前遇到过wait会get到毛刺导致环境认为已经达到wait条件就是不知道这个下降沿能不能规避这个问题vld0时对其他信号随机驱动为0/1/rand/x等run phase调用get_stim任务task get_stim() SEQ_TR tr; forever begins seq_item_port.try_next_item(tr); if(tr null) driver_idle(); else begin driver_pkt(); seq_item_port.item_done(tr); end endtask task driver_idle(); vif.data 0; vif.data 1; vif.data x; vif.data $urandom_range(1,9999); (posedge vif.clk) endtask多个激励源头驱动一个接口通过旗语来保证每一个时刻只有一个用户在驱动接口semaphore user_sm; user_sm new(1);//put 1 key task automatic drv_intf(type tr) user_sm.get(1);// //driver tr2intf do begin vif.vld 1; vif.info tr.info; (posedge vif.clk); end while( vif.rdy 0) ; vif.vld 0;//clr//support back2back user_sm.put(1);// endtask接受反压控制的驱动do begin (posedge vif.clk); if(this.vif.master.ready1) this.vif.master.valid b0; end while(!this.vif.master.ready); //或者这样 do begin this.vif.master.valid b1;//rdy不成立时要保持 (posedge vif.clk); this.vif.master.valid b0;//退出的时候下一拍为0 end while(!this.vif.master.ready);支持背靠背的驱动组件task xx_driver::send_tr(xx_item tr); vif.drv_cb.vld 1; vif.drv_cb.data tr.data; vif.drv_cb; vif.drv_cb.vld 0;//clr下一个的tr前面会给vld再次赋值 repeat(tr.tr_idle_num) vif.drv_cb;//控制接口时序的前面进来也可以搞一个不过感觉没必要上面这种背靠背有一个问题就是seq的start的启动时间是不确定的可能会出现信号缺失实际使用遇到了seq多次start后面的信号到送到了drv但是接口上没有看到信号生效。在前面先cloking_block后再把idle控制放到外面做可能更好。具体如下所示task xx_driver::send_tr(xx_item tr); vif.drv_cb; vif.drv_cb.vld 1; vif.drv_cb.data tr.data; endtask task xx_driver::drv_idle(xx_item tr); vif.drv_cb; vif.drv_cb.vld 0; endtask task xx_driver::str_process(xx_item tr); user_trans tr; forever begin wait(tr_que.size() 0);//seq发过来的tr会被drv放到这个que里面 tr tr_que.pop_front() send_tr(tr); repeat(tr.mi_tr_idle_num) drv_idle(tr); if(tr_que.size 0 tr.mi_tr_idle_num 0) drv_idle(tr);//特殊情况处理最后一个tr同时idle_num0就需要主动调用把vld拉回来 end endtask循环读有规律的寄存器利用 uvm_reg 的 get_reg_by_name wqe_union_t wqe_union; uvm_status_e status; bit [31:0] reg_val; bit [511:0] raw_data; uvm_reg reg_h; string reg_name; for (int i 0; i 16; i) begin reg_name $sformatf(sqp_last_err_sqe%0d, i); reg_h this.glb_xaction.ral_model.IT_DUT_csr.get_reg_by_name(reg_name); if (reg_h null) begin uvm_error(READ_ERR, $sformatf(Register %s not found, reg_name)) continue; end reg_h.read(status, reg_val, UVM_FRONTDOOR); raw_data[i*32 : 32] reg_val; end wqe_union raw_data;一些顶层架构策略多个qp共享全局信息和每一个qp的独享信息在验证环境架构上有一定体现

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价