摘要:简单易懂的PSS用例科普
Accellera的便携式测试和激励标准提供了强大的验证功能,这些功能并不能代替UVM,而是可以增加现有的验证流程。 这就是便携式激励和UVM相互作用的方式。
在开发便携式测试和激励标准时,有关它的最常见问题之一是:它打算替代UVM吗?”答案很明确:“不!” 要追其原因,我们需要研究一下 PSS与验证工具交互的方式,为了了解Accellera便携式测试和激励(PSS)标准与UVM的不同作用,让我们考虑从1.0a版本的标准文件中获得关于PSS打算完成的简短说明:
“目标是允许以较高的抽象级别指定激励和测试,包括覆盖率和结果检查,适用于工具来解释和创建方案,并在多种语言和工具环境中可生成实现,并且在整个行为的多种实现中具有一致性。”
由此可见,PSS模型本身不是可执行的。 相反,它需要一个工具来分析抽象模型并从中生成实现(测试)。 为UVM环境生成的测试只是可以从模型生成的实现之一。 正如UVM测试台被分成可执行元素(例如uvm_sequences)一样,它们在由uvm_components组成的测试台中执行(例如环境和代理),我们可以使用PSS模型来生成UVM测试台的可执行部分。 那些生成的片段仍然需要在其中运行的其余UVM环境。
让我们看一下用于随机测试生成的简单UVM序列:
简单的UVM随机序列:
class cb1_seq_item extends uvm_sequence_item;
`uvm_object_utils(cb1_seq_item);
rand bit [4:0] field1;
rand bit [4:0] field2;
constraint c1 {field1 < 10;}
constraint c2 {field2 < 10;}
function new(string name = “cb1_seq_item”);
super.new(name);
endfunction //new
…
endclass
class cb1_rand_sequence extends uvm_sequence#(cb1_seq_item);
`uvm_object_utils(cb1_rand_sequence);
cb1_seq_item item;
function new(string name = “cb1_rand_seq”);
super.new(name);
item = cb1_seq_item::type_id::create(“item”);
endfunction //new
task body();
start_item(item);
if(!item.randomize())
`uvm_fatal(“BAD_RAND”, “Item failed randomization”);
finish_item(item);
endtask //body
endclass //cb1_sequence
cb1 \ _rand \ _sequence在其构造函数中创建一个序列项,然后主体任务使用标准的UVM惯用法对该项进行随机化并将其发送给驱动程序。该项目本身包含两个随机字段,每个字段都限制为小于10。如果我们要运行UVM测试以在适当的序列发生器上启动此序列,则该测试将生成一个包含随机数据的单笔交易,并且随后完成。 如果我们跟踪数据字段的功能覆盖率,则交叉覆盖率将为1%。 (该算法的内容留给读者练习)。 就其本身而言,这不是一个特别有用的测试,但是在创建更复杂的场景时可能会有所帮助。
UVM中的这种情况可能涉及一个被称作cb1_rand_sequence的虚拟序列,可能还包括它可能执行的其他操作:
UVM虚拟序列:
class cb1_rand_vsequence extends uvm_virtual_sequence;
`uvm_object_utils(cb1_rand_vsequence);
cb1_rand_sequence test_seq;
cb1_env m_env;
function new(string name = “cb1_seq”);
super.new(name);
endfunction //new
virtual task body;
test_seq = cb1_rand_sequence::type_id::create(“test_seq”);
for(int i=0; i<100; i++) begin
test_seq.start(m_env.m_agent.m_seqr);
end
endtask
endclass
在cb1_rand_vsequence中,我们调用cb1_rand_sequence 100次,每次将为基础序列项生成一个随机值。 回想一下,SystemVerilog约束随机语义不会阻止重复相同的值。
这是从UVM测试调用的虚拟序列,以使事情发生:
class cb1_rand_test extends cb1_test_base;
`uvm_component_utils(cb1_rand_test);
cb1_rand_vsequence test_vseq;
…
task run_phase(uvm_phase phase);
phase.raise_objection(this, “Main”);
test_vseq = cb1_rand_vsequence::type_id::create(“test_vseq”);
test_vseq.m_env = m_env;
test_vseq.start(null);
phase.drop_objection(this, “Main”);
endtask
endclass
在典型的SystemVerilog模拟器中执行时,cb1_rand_vsequence在item.field1和item.field2的交叉处实现68%的覆盖率。
简单cb1_random_sequence的可移植激励标准等效项是一个action,它是PSS语言构造所表示的行为。
简单的PSS action:
struct cb1_struct {
rand bit [4:0] field1;
rand bit [4:0] field2;
constraint c1 {field1 < 10;}
constraint c2 {field2 < 10;}
}
action cb1_a {
rand cb1_struct data;
}
action是使用action关键字声明的,并且由括号{}分隔,就像PSS中的大多数构造一样。 该操作包含一个随机数据结构,该结构具有与UVM中的序列项相同的字段和约束。 action由处理工具组装成一个图形,该图形定义了构成模型的动作之间的调度关系和其他约束。 解决图形以生成测试时,遍历图形中的每个action节点,这将使其随机字段随机化。 因此,此操作表示数据结构的单个随机化,就像我们从UVM示例中的cb1 \ _rand \ _sequence中看到的那样。 但是,PSS模型仅说明目标测试实现中的随机结构应该做什么。
为了告诉处理工具如何将基本的PSS模型转变为实际的实现,我们必须在action声明中提供目标实现:
基本action的充分声明:
action cb1_a {
rand cb1_struct data;
exec body SV = “””
begin
cb1_transfer_sequence test_seq =
cb1_transfer_sequence::type_id::create(“test_seq”);
test_seq.item.field1 = {{data.field1}};
test_seq.item.field2 = {{data.field2}};
test_seq.start(m_env.m_agent.m_seqr);
end
“””;
}
exec主体块用于提供action的实现。 包含exec执行程序块的action在PSS中被称为“原子动作(atomic action)”。 在目标模板exec块中,我们使用大括号符号将值从抽象模型传递到生成的测试中。
处理工具根据PSS模型图中定义的调度将exec块的内容插入到结果测试中。 这包括数据结构字段的随机值。 当针对UVM环境时,PSS模型的实现将是UVM虚拟序列,因此将根据计划将exec块的内容插入虚拟序列。
UVM虚拟序列的实现:
class cb1_infact_xfer_seq extends cb1_rand_vsequence;
// Register sequence with UVM factory
`uvm_object_utils(cb1_infact_xfer_seq)
function new(string name = “cb1_infact_xfer_seq”);
super.new(name);
endfunction // new
task body();
begin
cb1_transfer_sequence test_seq =
cb1_transfer_sequence::type_id::create(“test_seq”);
test_seq.item.field1=64’d7;
test_seq.item.field2=64’d3;
test_seq.start(m_env.m_agent.m_seqr);
end
endtask
endclass
body方法的内容与PSS模型中exec块的内容完全相同,只是将预先随机化的值插入到生成的代码中。
为了防止cb1 \ _rand \ _sequence中项目的额外随机化,我们需要在UVM中创建一个新的cb1 \ _transfer \ _sequence“帮助程序序列”:
用于PSS实现的UVM帮助程序序列:
class cb1_transfer_sequence extends cb1_rand_sequence;
`uvm_object_utils(cb1_transfer_sequence);
function new(string name = “cb1_xfer_seq”);
super.new(name);
endfunction // new
task body();
start_item(item);
finish_item(item);
endtask
endclass
基类中仍然存在item字段,但是由于值是从虚拟序列填充的,因此我们只需执行start \ _item()-finish \ _item()即可执行预随机交易。 UVM的模块化允许我们通过使用简单的工厂覆盖,在用于UVM的同一cb1 \ _rand \ _test中使用生成的cb1 \ _infact \ _xfer \ _seq虚拟序列。
> vsim cb1_tb + UVM_TESTNAME = cb1_rand_test \
+uvm_set_type_override = cb1_rand_vsequence,cb1_infact_xfer_seq
如果我们用作PSS模型的全部只是原子动作(action),那么我们就和UVM中的cb1_rand_sequence处于同一条船上,在这里我们仅执行一次事务。 在那里,两个数据字段的100种可能组合的交叉覆盖率为1%。 相反,我们可以在PSS中创建一个复合动作(action),该action将重复使用cb1_a action来创建类似于上述cb1_rand_vsequence的方案。
PSS中的复合action:
action cb1_loop {
cb1_a cb1;
activity {
repeat(100) {
cb1;
}
}
}
PSS中的活动语句描述了模型中action的实际调度图。 在此示例中,我们使用重复构造将cb1_a action遍历100次。 使用此模型,PSS处理工具可以分析结果图并在UVM中创建虚拟序列,以实现100%的覆盖率。 这是程序性激励描述(例如UVM序列)和声明性激励描述(例如PSS)之间的主要区别。
图. 一个PSS工具可从单个模型中生成多种方案
实际图形是PSS工具将在生成目标实现之前对其进行静态分析,而不是在同一操作上循环执行100次的图形,这是一个循环,在该循环中,每次迭代都选择一个action实例,每个工具都会选择一个实例可以应用数据值的唯一组合。 SystemVerilog和UVM无法先验地静态分析程序激励序列以进行此优化。
因此,我们相对简单的PSS模型定义了100个独特的场景。通过生成结果实现中的每个唯一方案,我们可以生成一个测试,该测试将在最少100次迭代中实现完全覆盖。 PSS模型的声明性性质使用户能够以有效且紧凑的方式使用活动图来捕获大量可能的场景。然后,以覆盖率为中心的PSS工具将使用覆盖率目标来限制活动图的解决方案空间,以针对实现那些覆盖率目标所需的方案生成最小的特定于目标的实现集。一旦满足了覆盖目标,就可以生成其他实现。尽管这些实现超出了覆盖目标,但根据模型中定义的调度和其他约束仍然合法。
正如我们在本示例中看到的那样,使用PSS模型来定义用于验证的测试意图具有明显的优势,但是PSS模型将仅替换您的UVM测试平台的一部分。具体来说,它将生成一组UVM虚拟序列,您可以从UVM测试中运行该序列,从而使优化的激励在您现有的UVM环境中运行。您还可以从相同的PSS模型生成C代码,因此当您的验证工作从UVM仿真环境转移到仿真或FPGA原型中的基于处理器的环境时,您可以重用测试意图。
作者
汤姆·菲茨帕特里克(Tom Fitzpatrick)自成立以来一直是积极活跃的Accellera成员,在Accellera的技术工作组中担任许多重要的领导职务。 他还是2019年Accellera技术卓越奖的获得者。 有关Accellera便携式激励标准的更多信息,请访问“便携式激励工作组”页面(https://accellera.org/activities/working-groups/portable-stimulus/)。 有关Accellera UVM标准的更多信息,请访问UVM工作组页面(https://accellera.org/activities/working-groups/uvm)。
原文链接:https://www.techdesignforums.com/practice/technique/portable-stimulus-and-uvm/
扫描上图二维码可直达课程页面,马上试听
往期精彩:
路科发布| 稳中带涨!25w成芯片校招薪资平均底!2020应届秋招数据全面分析!
理解UVM-1.2到IEEE1800.2的变化,掌握这3点就够