UVM验证平台用例卡死的一个可能原因-clockingblock

这是一个我在工作中遇到的问题,简单记录一下解决方法,方便以后回顾,或者能够帮助到陷入相同困境的同学。

 首先看一下interface部分的代码,可以更直观的看到cb和clk分别是什么位置:

interface stream_if(input bit clk, input bit rst_n);

    ...

    clocking cb @(posedge clk);

        ...

    endclocking

endinterface

简单来说就是在driver中发送激励时,使用了固定次数的循环,其中需要添加时钟保证发送的激励和rtl的时钟可以对上。比如语句:

@vif.cb;

又或者:

@vif.clk;

这两者都能帮助driver与rtl或者说interface进行同步,但是又有不同,cb(clocking block)仅会由上沿触发(或者说根据这个clocking block的敏感列表),而clk的双沿均会触发,错误地使用它们会使激励的发送节奏过快/过慢,导致循环不能正确结束,卡住整个用例的进程。

如果使用了循环,又出现了用例卡死,不妨检查一下clocking block的相关代码~

### 搭建集成寄存器模型的UVM完整验证平台 #### 1. 定义寄存器模型 在UVM中,寄存器模型的核心组件包括`uvm_reg`、`uvm_reg_field`、`uvm_reg_block`和`uvm_reg_map`。这些类用于描述寄存器及其字段,并定义它们的地址映射关系[^3]。 以下是一个简单的寄存器模型定义示: ```systemverilog class my_reg extends uvm_reg; rand uvm_reg_field fifo_full; rand uvm_reg_field fifo_empty; function new(string name = "my_reg"); super.new(name, 32, UVM_NO_COVERAGE); endfunction virtual function void build(); fifo_full = uvm_reg_field::type_id::create("fifo_full"); fifo_full.configure(this, 1, 0, "RW", 0, 32'h1, 1, 1, 1); fifo_empty = uvm_reg_field::type_id::create("fifo_empty"); fifo_empty.configure(this, 1, 1, "RW", 0, 32'h0, 1, 1, 1); endfunction endclass class my_reg_block extends uvm_reg_block; rand my_reg R1; function new(string name = "my_reg_block"); super.new(name, UVM_NO_COVERAGE); endfunction virtual function void build(); default_map = create_map("default_map", 'h0, 4, UVM_LITTLE_ENDIAN); R1 = my_reg::type_id::create("R1"); R1.build(); R1.configure(this); R1.add_hdl_path_slice("top.R1", 0, 32); default_map.add_reg(R1, 'h0, "RW"); endfunction endclass ``` #### 2. 集成寄存器模型到验证环境中 寄存器模型需要集成到UVM验证环境中,通常通过创建寄存器模型实并将其与验证环境中的其他组件关联来实现。 以下是一个,展示如何将寄存器模型集成到UVM环境: ```systemverilog class my_env extends uvm_env; my_reg_block reg_model; uvm_sequencer #(uvm_sequence_item) sequencer; uvm_reg_adapter reg_adapter; function new(string name, uvm_component parent); super.new(name, parent); endfunction function void build_phase(uvm_phase phase); super.build_phase(phase); reg_model = my_reg_block::type_id::create("reg_model"); reg_model.build(); reg_model.lock_model(); reg_adapter = uvm_reg_adapter::type_id::create("reg_adapter"); reg_adapter.byte_enable_support = 0; reg_adapter.little_endian = 1; uvm_config_db#(uvm_reg_block)::set(this, "*", "regmodel", reg_model); endfunction function void connect_phase(uvm_phase phase); super.connect_phase(phase); reg_model.default_map.set_sequencer(sequencer, reg_adapter); endfunction endclass ``` #### 3. 使用寄存器模型进行读写操作 一旦寄存器模型集成到验证环境中,可以通过调用`read`和`write`方法执行寄存器的读写操作[^3]。 以下是一个读写操作的示: ```systemverilog task automatic reg_access_example(output uvm_status_e status, output uvm_reg_data_t value); reg_model.R1.read(status, value, UVM_FRONTDOOR); if (status != UVM_IS_OK) begin `uvm_error("REG_ACCESS", "Read operation failed") end reg_model.R1.write(status, 16'h1, UVM_FRONTDOOR); if (status != UVM_IS_OK) begin `uvm_error("REG_ACCESS", "Write operation failed") end endtask ``` #### 4. 测试寄存器模型 UVM提供了多种内置序列(sequence)用于测试寄存器模型,如`uvm_reg_hw_reset_seq`、`uvm_reg_bit_bash_seq`等。这些序列可以帮助验证寄存器的功能和边界条件[^2]。 以下是一个测试寄存器模型的示: ```systemverilog class my_test extends uvm_test; my_env env; function new(string name, uvm_component parent); super.new(name, parent); endfunction function void build_phase(uvm_phase phase); super.build_phase(phase); env = my_env::type_id::create("env", this); endfunction task run_phase(uvm_phase phase); uvm_reg_hw_reset_seq reset_seq; uvm_reg_bit_bash_seq bash_seq; phase.raise_objection(this); reset_seq = uvm_reg_hw_reset_seq::type_id::create("reset_seq"); reset_seq.model = env.reg_model; reset_seq.start(null); bash_seq = uvm_reg_bit_bash_seq::type_id::create("bash_seq"); bash_seq.model = env.reg_model; bash_seq.start(null); phase.drop_objection(this); endtask endclass ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值