资讯动态

UVM Sequence 机制深度解析:握手时序、仲裁与锁机制(附面试速记)

发布时间:2026/10/18 0:29:13 来源:尧图企业网站定制
一、sequence-driver 握手时序波形Mermaid时序图 文字拆解场景标准2步握手start_item/finish_itemget_next_item item_done核心finish_item阻塞直到driver调用item_done才返回driversequencersequencedriversequencersequence初始状态driver卡在get_next_item等待itemget_next_item(req) 返回拿到事务sequence 可以创建下一个item循环start_item(req) 【申请权限】允许不阻塞randomize(req)finish_item(req) 【发送itemSEQ阻塞】推送req到driver驱动DUT信号消耗多个时钟周期item_done() 【通知完成】finish_item 解除阻塞SEQ继续往下执行时序关键点start_item(req)向sequencer请求仲裁权限如果有其他sequence抢sequencer这里会阻塞。finish_item(req)把item放入sequencer阻塞等待driver处理完item_done。get_next_item(req)driver阻塞调用没有item就停在这里。拿到item后sequencer不再给新item。item_done()释放当前transactionsequencer唤醒sequence。一句话时序记忆start_item拿权限 → 随机化 →finish_item发item并卡住 → driverget_next_item拿到 → 驱动DUT →item_done释放 → sequence解除阻塞。二、virtual sequence多sequence抢占同一个sequencer的仲裁机制2.1 基础概念virtual sequence虚序列本身不挂载sequencer不产生item它只负责启动多个子sequence。多个子sequence可以挂在同一个sequencer上并发发送transaction。例seqA写操作、seqB读操作两个sequence同时start到同一个seqr两者会竞争sequencer的授权这个就是sequencer仲裁。区分normal sequenceextends uvm_sequence#(item)必须挂载sequencer。virtual sequenceextends uvm_sequence #(uvm_sequence_item)p_sequencernull只调度子sequence。2.2 Sequencer仲裁原理sequencer内部维护请求队列当多个sequence同时调用start_item()时就会向sequencer提交申请。UVM内置5种仲裁算法uvm_sequencer::set_arbitration()设置SEQ_ARB_FIFO // 0: 先进先出默认先来先服务 SEQ_ARB_WEIGHTED // 1: 加权随机权重高的更容易拿到授权 SEQ_ARB_RANDOM // 2: 纯随机 SEQ_ARB_STRICT_FIFO // 3: 严格优先级FIFO高优先级优先同优先级FIFO SEQ_ARB_STRICT_RANDOM//4: 严格优先级随机高优先级优先同优先级随机仲裁流程重点面试多个sequence并发执行start_item()全部进入sequencer的request queue排队。sequencer根据仲裁算法选出其中一个sequence授予权限。被选中的sequencestart_item返回继续randomize执行finish_item发送item。这个item被driver取走直到item_done()完成。当前transaction结束sequencer重新执行一轮仲裁再从等待队列里选下一个sequence。⚠️ 重要同一个sequencer同一时刻只允许一个sequence拥有发送item的权限也就是同一时间只能有一笔transaction在传输。多个sequence是分时复用sequencer。最小demovirtual sequence 并发两个seq抢占同一个seqrclass virt_seq extends uvm_sequence; uvm_object_utils(virt_seq) uvm_declare_p_sequencer(my_sequencer) my_seq_wr seq_wr; my_seq_rd seq_rd; virtual task body(); fork seq_wr my_seq_wr::type_id::create(seq_wr); seq_wr.start(p_sequencer); seq_rd my_seq_rd::type_id::create(seq_rd); seq_rd.start(p_sequencer); join endtask endclass在test中启动virt_seq挂载到env.seqrseq_wr、seq_rd两个sequence抢同一个sequencer由sequencer仲裁。2.3 sequence优先级在start_item可以设置优先级start_item(req, 100); //第二个参数是priority数字越大优先级越高只有SEQ_ARB_STRICT_FIFO / STRICT_RANDOM才会识别优先级默认FIFO模式忽略优先级。三、try_get_next_item非阻塞版本 lock/grab锁机制3.1 try_get_next_item() —— 非阻塞取item标准get_next_item()是阻塞任务task没有item就一直等卡住driver。try_get_next_item(req)是函数function非阻塞返回值1拿到item0sequencer没有可用item直接返回不会卡住。代码示例virtual task run_phase(uvm_phase phase); my_item req; forever begin if(seq_item_port.try_get_next_item(req)) begin //成功拿到item驱动DUT uvm_info(DRV, $sformatf(get item data%0d,req.data),UVM_MEDIUM) #10ns; seq_item_port.item_done(); //依旧必须成对调用item_done end else begin //没有item不阻塞可以做别的事情比如喂看门狗、检测复位 uvm_info(DRV,No item available, do other job,UVM_LOW) #1ns; end end endtask✅ 使用场景driver需要并行处理别的逻辑监控复位、检测中断不能一直卡在阻塞等待item。⚠️ 约束如果try拿到item后续仍然必须调用item_done()配对规则不变。配套APItry_get(req)非阻塞版本get成功则内部自动item_done。3.2 lock / grab 锁机制sequence独占sequencer默认仲裁每发完1个itemsequencer重新仲裁别的sequence有机会抢。lock/grab拿到锁的sequence独占sequencer连续发送多个item中间不释放别的sequence无法抢占。lock()task body(); my_item req; //申请锁阻塞直到拿到sequencer独占权 p_sequencer.lock(this); repeat(5) begin req my_item::type_id::create(req); start_item(req); assert(req.randomize()); finish_item(req); end p_sequencer.unlock(this); //释放锁必须手动释放 endtasklock(this)阻塞等待获取锁锁属于当前sequence句柄拿到锁之后只要该sequence不断发itemsequencer不会重新仲裁其他sequence的start_item全部阻塞排队。必须调用unlock()释放忘记unlock → 其他sequence永久卡死。grab()p_sequencer.grab(this); // 发送一批item p_sequencer.ungrab(this);grab和lock功能几乎一致唯一差别优先级lock排队等待和普通sequence一起参与仲裁grab高优先级抢占。只要调用grab会排在所有普通请求、lock请求前面优先拿到sequencer。对比总结API特点lock普通排队拿到锁后独占sequencer直到unlockgrab插队抢占优先级高于lock和普通sequence拿到后独占ungrab释放使用场景突发连续传输burst写需要一次性连续发10个写事务中间不能被读sequence打断→ 使用lock/grab。注意lock/grab只锁住sequencer的item发送权限不会影响已经在driver中正在处理的transaction。如果driver正在处理一个item此时sequence调用grab需要等当前item_done完成后grab才生效。释放锁的坑必须unlock/ungrab否则仿真死锁。锁是绑定sequence句柄A sequence拿到lock只有A可以unlock别的sequence调用unlock无效。is_locked()函数可以查询sequencer当前是否被锁住。面试速记小结时序start_item(拿权限) → randomize → finish_item(阻塞) → driver get_next_item →驱动 → item_done 释放virtual sequence不挂载seqrfork启动多个子seq子seq竞争同一个sequencersequencer支持5种仲裁策略。默认FIFO。try_get_next_item非阻塞function拿不到item直接返回拿到item依旧需要item_done。lock/grab独占sequencer。lock排队grab插队抢占用完必须unlock/ungrab。

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

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

免费获取报价 →
↑