2024/04/17
gVim使用
- 逐字替换:R开启gVim替换模式;r只能替换光标的字符
- 逐字删除:X逐字删除光标前的字符;x逐字删除光标后的字符
- 多行复制:yy复制光标当前行,nyy复制光标后的n行代码,按p粘贴(鼠标中键无法粘贴nyy复制内容)
- 多行剪切:dd剪切光标当前行,ndd剪切光标后的n行代码,按p粘贴(鼠标中键无法粘贴ndd复制内容)
2024/04/18
Verdi使用
- 使用场景:Verdi查看UVM层次结构
- 用户手册:《Verification ContinuumTM Verdi UVM Debug User Guide》, 可以在$VERDI_HOME/doc中找到。
- 操作方法:CSDN 劲仔小鱼
- 注意事项:设置完参数后,先compile,再打开Verdi的Simulation→Invoke Simulator,然后就可以在console中输入所需要执行的指令。
2024/04/19
UVM(objection机制)
- 作用:UVM通过objection机制来控制验证平台的关闭。包括raise_objection和drop_objection。
- 场景:在进入某一phase时,UVM会收集该种phase raise的所有objection,并且实时监测所有objection是否已经被撤销。当发现所有objection都已经被撤销后,会关闭该种phase,开始进入下一种phase。当所有phase都执行完毕后,会调用$finish将整个验证平台关掉。
- starting_phase:在uvm_sequence这个基类里有starting_phase这个成员变量,它的类型是uvm_phase。sequencer在启动sequence时,会自动执行如下操作。
task my_sqr::main_phase(uvm_phase phase);
seq.starting_phase = phase;
seq.start(this);
endtask
因此,可以通过uvm_phase p=get_starting_phase()是否为null,来判断sequence是否需要raise/drop_objection。
2024/04/22
UVM(factory机制)
- 作用:为了能够方便地替换环境中的实例或者已注册的类型,从而提高环境的可重用性和灵活性。
- 步骤:注册→创建→重载
- 在遇到[NOA]Null object access问题时,可以在问题代码前后加上
`uvm_info("GTN", $sformatf("env:%s\n", env.get_type_name()), UVM_LOW)
- get_name()、get_type_name()、get_full_name()的区别如下,详见CSDN 小wang的IC自习室。
- get_type_name():返回对象的class名;
- get_name():返回创建对象时,传入的字符串;
- get_full_name():在component类会返回当前component组件的完整路径,在object类的返回值与get_name()一样,因为object类不是作为UVM树节点的,所以路径没有别的层次。
2024/04/23
UVM(寄存器模型):
- 使用
set_auto_predict(1)
,会自动调用uvm_reg::predict
方法更新镜像值
与期望值
- 通过monitor获得总线上的读写transaction,在经过新增的predictor和adapter组件,更新寄存器模型的
镜像值
与期望值
- 白皮书:当总线上只有一个master设备时,法一和法二是完全等价的。当总线上有多个主机时,法一会漏掉某些transaction。
gVim使用:
1. 单词复制:yw复制一个单词(包括空格),ye复制一个单词(不包括空格),鼠标中键粘贴
2. 单词复制:yiw复制一个单词(不包括空格),鼠标中键粘贴
3. 单词选中:viw选中一个单词(v表示进入visual模式),一般配合U或u进行大小写操作
2024/04/26
AHB总线
htrans有以下4种含义,详见CSDN filp-flop:
2024/04/28
SystemVerilog使用(typedef class)
- 场景:类互相包含,导致编译顺序无法满足的情况
- 作用:可以通过
typedef class
提前声明其他被包含的类
typedef class cfg_sequence;//提前声明!!就可以先编译base_sequence.sv,再编译cfg_sequence.sv
class base_sequence extends uvm_sequence;
...//常规定义
ral_block_pwm rgm;//从top_env拿到了寄存器模型
cfg_sequence pcfg;//需要子类来配置时钟源
virtual task body();
...
`uvm_do_on_with(pcfg, p_sequencer.x_vsqr[0],
{kind == cfg_sequence::SET_CLK_SRC;
chan == 16'hffff;})
...
endtask
endclass
//当你需要从模块的父类拿到寄存器模型和变量时,就可能需要定义一个子类继承于base_sequence
class cfg_sequence extends base_sequence;
...//常规定义
task body();
rgm.CSRC.read(status, rd_val);
...
rgm.CSRC.write(status, wr_val);
endtask
endclass