一个工厂小demo实现UVM的run_test

run_test是UVM的一大卖点. run_test根据运行时的参数+UVM_TESTNAME=[test_name]来例化[test_name]对应的继承自UVM_TEST的子类对象并运行. 把所有的用例一起编译之后, 就可以实现”一次编译, 多次运行”.

说到UVM的Factory工厂, 大家的第一反应可能是Factory的create例化:

1
2
usr_obj = usr_ojbect_class::type_id::create("obj_name");
usr_com = usr_com_class::type_id::create("com_name", this);

仔细看的话, 这种例化方式, 已经把对象的类型都写明了, 仍然是Hardcode硬编码的形式. 对比之下, run_test才是真正符合工厂模式内涵的动态行为.

这里用一个轻量级的demo来展示UVM的工厂模式实现run_test这种行为的机制.

Read More

UVM Commandline Processor

UVM的CLP(Commandline Processor)出现在源码文档的倒数第二章, 而最后一章的标题是”GLOBALS”, 也就是说UVM Command Processor是源码文档中的最后一个主题类.

这个类从字面上来看, 是处理仿真器的命令行参数的. 在看到这个类的时候, 我的直觉是这个类会不会是用SV的$plusargs实现的. 这次就来探索一下这个类吧.

CLP的API

这些内容都是文档里面直接给出的, 先是基本对象接口:

API Description
get_inst Returns the singleton instance of the UVM command line processor.

表明这个类是个单例类, 这个好理解, 因为命令行的处理只需要做一次, 得到的参数保留一份就够了.

Read More

UVM源码探索之Factory(下篇)

[TOC]

到下篇的时候, 我们来探索一下UVM的Factory的另外一个主要功能, 那就是重载. 说起来, 重载功能跟Factory这个设计模式已经没有关系了. 而且, 这里的”重载”跟常见的重载的意义也不一样, 这里的重载准确的描述的话是类”替换”.

在UVM里面使用重载的大致流程如下:

  1. 对需要重载的类使用uvm_*_util进行类型注册, 原始类和重载类都需要注册;
  2. 设置重载, 设置原始类”替换”为重载类;
  3. 使用Factory的create创建原始类对象, 返回的是重载类对象.

步骤1我们在上篇已经讲过了, 步骤2跟3的在上篇其实也有相关的代码展示, 不过我们略过了. 现在到了下篇, 我们的主要任务就是把上面流程中的2跟3的源码实现给搞清楚.

Read More

UVM源码探索之Factory(上篇)

[TOC]

这篇笔记是我在学习UVM的Factory源码的时候的一些记录跟总结, 整理为分为上下两篇. 上篇讲述的是uvm_object的Factory实现, 下篇再讲一些UVM Factory的其他功能. 使用的源码是uvm-1.2.

Factory机制是UVM的一个重要的底层机制, 内容不多, 源码规模来讲2000行上下. 相对sequence, 寄存器模型, TLM这些大部头来讲, Factory规模小, 独立性强, 是个很好的UVM学习源码的切入点.

我眼中的Factory

讲述工厂模式的书会告诉你, 工厂模式可以让你动态的生成对象(这其实是句废话啦, 对象其实都是动态也就是运行时生成的), 比如用字符串为参数生成指定的对象.

根据这个描述, UVM的Factory在我想象中是这样的:

Read More

Verification匠心

[TOC]

这篇笔记用于记录一些验证工作过程中的一些有益的小技巧和总结.

Makefile中空变量有大用

做数字验证的时候, 仿真器的编译和运行需要很多的编译运行参数, 一般Makefile里面就会写了很多东西了. 不过, 大多数时候, 在验证平台的调试阶段, 你会需要添加很多额外的编译选项和运行选项比如编译时添加-debug_all编译为行调试模式, 运行时添加+ntb_opt random_seed=<n>指定随机种子运行. 另外, UVM也引入了很多的运行参数.

Read More

Systemverilog的OOP相关语法特性来自于哪里

[TOC]

Systemverilog的语法内容非常丰富. 一般认为, Systemverilog的语法除了一些基础语法元素之外, 可以明显的分成四个部分: 与Verilog兼容的RTL部分, 断言(SVA)部分, 功能覆盖率(FC)部分和面向对象(OOP)部分.

其中OOP部分作为各种验证方法学的基础, 是Systemverilog中最重要的内容了. Verilog跟Systemverilog的关系, 很容易让人联想到C跟C++的关系, 再加上verilog的基础语法部分基本都是C语言里的(把begin-end换成大括号), 那是不是Systemverilog的OOP语法特性是来自于C++的呢?

Read More

我的Verilog HDL代码快速编辑环境

[TOC]

概述

由于工种的特殊性,Verilog可以说是一门朴实到简陋的设计语言,由于语法功能都非常的底层,因此在做规模比较大的设计的时候,Verilog代码必定是密密麻麻、相当繁琐的。

于是从开始做FPGA开始,我就在不断的探索verilog的编辑方案。使用的编辑器完成了从IDE自带编辑器到Notepad++到Emacs到Vim的变迁。

其实我这么做的还有一个很大的推力,就是IDE自带的编辑器实在太差。我用的是Quartus II,里面的代码编辑器连换行缩进都会出问题,而且语法高亮也太过简陋,还比不上Notepad++这种通用编辑器,简直不像是一个Verilog的IDE,跟VS一比更是不忍直视。不过也要感谢Quartus,让接触学习了Emacs和Vim,并因此顺带学到了很多相关的技巧和思维。

目前,我使用的这套Verilog编辑环境是以gVim作为主编辑器的,此外还用到了Emacs的verilog-mode和snipmate插件。

Read More

《Learning PERL》笔记

[TOC]

scalar和array的记法

1
2
$calar --> scalar
@rray --> array

还是挺巧妙的, 不过%hash就没什么的了.

字符串tricks

犀利的qw

qw表示quoted words:

1
2
qw(fred barney betty wilma dino)
# equals ("fred", "barney", "betty", "wilma", "dino")

此外, 用了qw就不限于用括号序对了, 可以用的序对符有:

1
2
3
4
5
6
7
qw!...!
qw/.../
qw#...#
qw{...}
qw[...]
qw<...>
...

好灵活的。

a..b递增数字序列

生成(a, a+1, a+2,..., b-1, b),这里当然b是要大于a的. 测试了一下, a大于b的话返回的是一个空列表.

Read More

$readmem是可综合的

[TOC]

之前在做了一个verilog版的呼吸灯,主要思路是把正弦信号调制到PWM里面循环输出。这个工程目前还处于还处刚刚完成仿真(用的ModelSim)的阶段,其中里面的正弦波数据是这样调用的:

1
2
3
4
5
reg [19:0] mem[199:0];
initial
begin
$readmemh ("sine.dat", mem);
end

之前需要用到正弦波数据的时候,都是老老实实的用ROM IP+Matlab+mif文件来实现的。这还是我第一次用$readmem,之前只知道这个语句是不可综合的。当时手头没有板子可以用,心想还是快点弄个出来先仿真,于是就用了这个了,数据文件也是直接用Python弄出来的(Python真是好)。

近来开始换用Vivado了,从A家换到X家,从新开始,很老实的看各种官方User Guide,然后就在机缘巧合之下,突然看到一篇文档里面直接提到说$readmem是可综合的。这个发现让我很震惊,这个带$的语句竟然是可综合的?!然后我又回头翻Quartus的文档,发现原来$readmem在Quartus里面也是可以综合的。思维定势蒙蔽了我的双眼,这个语句要是可综合的那用起来可就方便多了。

Read More