0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

FPGA EDA软件的位流验证

FPGA设计论坛 ? 来源:松山湖开发者村综合服务 ? 2025-04-25 09:42 ? 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

位流验证,对于芯片研发是一个非常重要的测试手段,对于纯软件开发人员,最难理解的就是位流验证。在FPGA芯片研发中,位流验证是在做什么,在哪些阶段需要做位流验证,如何做?都是问题。

我们先整体的说一下:

首先:在硬件设计阶段,位流验证是设计验证部的重要工作,它是为了验证硬件设计的数字电路部分的合理性,对于FPGA芯片,主要就是对标准的架构组件进行验证。如果相应的EDA软件未成形之前,相应的位流需要通过手工单独生成。

然后:在FPGA配套的EDA软件开发阶段,位流验证也非常重要。因为EDA软件的最大目标就是生成正确的位流,位流输出是否符合预期,关系到软件各个环节的正确性。所以,一般会将位流验证做为重要的回归测试手段,一方面,可以持续验证最新输出软件的正确性,另外,如果芯片的底层架构发生变化,模型变更,仿真库变更,也可以通过位流验证,保证架构更改的正确性(架构主要是按照硬件设计对应的软件模型,而硬件设计的这些模型,都会有对应的仿真库和参考模型,用于验证)。

最后:在生产测试阶段,位流验证同样是非常好的测试手段,它可以测试位流写入芯片后上板上芯片的效果,确认芯片实际的运行情况。在软件中只是保证了逻辑上的正确,实际结合电气特性和各种不同环境是否能正常可靠运行,可能通过位流加载后的效果进行验证。加载到实际板上的效果,也可以通过驱动程序取出,与预期参老模型的结果做对比,验证其准确性。

当然,位流验证可能并不仅限于上面的三种情况(限于我了解的内容有限),但通过上面的描述,你可以发现,位流验证本身是就是会跨多个部门的比较特殊的手段,在不同部门做验证时,一定会存在配合,和一些有相似的工作。但是,因为各自的目的不同,发现错误后,定位和纠错的方向也很不一样。反以,反过来说,选择的相应示例也会有些不同。

今天,我们只讲在EDA软件如何利用位流验证,完成对EDA软件的重要回归测试。

大概的讲法是:

:我们会讲解位流验证依赖的框架UVM

:会讲一下UVM的实现平台。

:会讲一下针对EDA软件的验证,会对哪些部分进行验证,会使用什么样的示例 。

:发现问题后,会如何通过输出去定位错误。

:因为用于自动化回归,也讲一下相应的自动化平台应该如何拱建。

首先,我们还是得再来理解一下位流验证需要用到的UVM框架。

一:UVM框架

1.1:理论

Universal Verifacation Methodology:是一套基于SystemVerilog的标准验证方法学。它提供了一套完整的框架,用于构建复杂的验证环境,应用于芯片设计领域的功能验证。旨在提高验证的可重复性、可重用性和自动化程度。应该说,对于硬件设计的验证,UVM是最基础,最常用的平台,离不开它。

e59f58d8-201e-11f0-9310-92fbcf53809c.jpg

2.1.1:DUT

待测设计——Design Under Test,就是你要验证的设计单元。

如果你是要验证/测试一颗 FPGA 芯片,DUT 一般会分为三种,一种是单Tile的设计,一种是多Tile的设计,还有就是整个芯片的设计。

注意这里我加了个bitstream,这并不是UVM必须的,加上bitstream是和我们今天要讲的位流验证扣题,也就是我们在验证时,使用FPGA的位流文件,来形成DUT的功能。

env:Testbenc Environment ,除了DUT,其它就是UVM的验证环境了,它包含了一大堆东西,后面一个一个介绍。

Sequencer:测试数据序列,因为测试时需要很多的输入数据,我们按序列提供。

Driver:如何数据输入DUT的过程,可以理解为激励的过程。

Monitor:监控DUT的输入/输出信号

Reference Model:参考模型,对应DUT的设计,提供相同行为的给果。

这里参考模型的运行,一般我们会使用仿真工具的内置实现来完成。

Compare:比较DUT的输出和参考模型的输出,判断是否匹配。

2.1.2:Sequencer

Sitmulus:生成测试数据序列。我们需要基于测试的需求,产生数据,交给Driver来驱动到DUT。比如:你要测试DSP的乘法,那就是提供相应的输入数值对。

class my_sequence extends uvm_sequence #(my_transaction);


`uvm_object_utils(my_sequence)

task body();
my_transaction tr;
foreach (tr.data[i]) begin
tr.data[i] = $urandom_range(0, 255); // 随机生成 8 位数据
start_item(tr); // 发送数据
finish_item(tr);
end
endtask
endclass

2.1.3:Driver

接收Sequencer的测试数据并将其转换为DUT的输入信号。

这里可能需要模拟时序,比如:时钟的同步,握手协议等。

class my_driver extends uvm_driver #(my_transaction);


`uvm_component_utils(my_driver)

task run_phase(uvm_phase phase);
forever begin
seq_item_port.get_next_item(req); // 接收 sequencer 的数据
@(posedge clk); // 时钟同步
dut_input = req.data; // 将数据驱动到 DUT
seq_item_port.item_done();
end
endtask
endclass

2.1.4:Monitor

实时监控DUT的输入和输出信号,将监控到的数据送出到比较系统Compare,进行输出分析。

class my_monitor extends uvm_monitor #(my_transaction);
`uvm_component_utils(my_monitor)

task run_phase(uvm_phase phase);
forever begin
@(posedge clk);
tr.data = dut_output; // 采集 DUT 的输出数据
analysis_port.write(tr); // 将数据发送给 Scoreboard
end
endtask
endclass

2.1.5:Reference Model

参考模型,用于生成和DUT相同逻辑功能的输出(Golden Model)。

基于相同的输入激励信号,获得理想的输出。

function bit [7:0] ref_model(input bit [7:0] data);
return data + 1; // 示例:参考模型输出为输入加 1
endfunction

2.1.6:Compare

这里的Compare,可能是简单的比较结果的输出,也可能是比较复杂的Scoreboard(一个记录数据表)。根据比较结果,输出不匹配的情况,并输出报告。

class my_scoreboard extends uvm_scoreboard;


`uvm_component_utils(my_scoreboard)

task run_phase(uvm_phase phase);
my_transaction ref_tr, dut_tr;
forever begin
ref_tr = ref_fifo.get(); // 从参考模型接收预期数据
dut_tr = dut_fifo.get(); // 从 DUT 获取实际输出
if (ref_tr.data !== dut_tr.data)
`uvm_error("Mismatch", $sformatf("Expected: %0h, Got: %0h", ref_tr.data, dut_tr.data));
end
endtask
endclass

2.1.7:示例

我们再来一个完整的示例,说明一下各部分做的事情。

DUT设计—— 一个简单的8位加法器。

DUT代码:(对于位流验证,输入不是这个,后面会举例说明)

module adder(
input logic [7:0] a,
input logic [7:0] b,
output logic [7:0] sum
);
assign sum = a + b;
endmodule

UVM环境:

这里需要定义一个Transaction,因为每次激励的执行都是不同的事务,事务标明输入和输出。

Transaction 定义:

class my_transaction extends uvm_sequence_item;
rand bit [7:0] a, b; // 输入信号
bit [7:0] expected_sum; // 参考模型生成的期望输出

`uvm_object_utils(my_transaction)

// 构造函数
function new(string name = "my_transaction");
super.new(name);
endfunction
endclass

Sequencer:

class my_sequence extends uvm_sequence #(my_transaction);


`uvm_object_utils(my_sequence)

task body();
my_transaction tr;

repeat (10) begin
tr = my_transaction::create("tr");
tr.a = $urandom_range(0, 255); // 随机生成输入 a
tr.b = $urandom_range(0, 255); // 随机生成输入 b
start_item(tr); // 开始传输数据
finish_item(tr); // 结束传输数据
end
endtask
endclass

Driver:

class my_driver extends uvm_driver #(my_transaction);


`uvm_component_utils(my_driver)

// DUT 的接口
virtual adder_if dut_if;

// 构造函数
function new(string name = "my_driver", uvm_component parent);
super.new(name, parent);
endfunction

// 运行阶段
task run_phase(uvm_phase phase);
forever begin
seq_item_port.get_next_item(req); // 从 Sequencer 获取数据
@(posedge dut_if.clk); // 等待时钟上升沿
dut_if.a = req.a; // 驱动 DUT 输入 a
dut_if.b = req.b; // 驱动 DUT 输入 b
seq_item_port.item_done(); // 标记数据已完成
end
endtask
endclass

Monitor:

输入监控

class input_monitor extends uvm_monitor;


`uvm_component_utils(input_monitor)

// DUT 接口
virtual adder_if dut_if;
uvm_analysis_port #(my_transaction) analysis_port; // 分析端口

function new(string name = "input_monitor", uvm_component parent);
super.new(name, parent);
endfunction

// 运行阶段
task run_phase(uvm_phase phase);
forever begin
@(posedge dut_if.clk); // 等待时钟上升沿
my_transaction tr = my_transaction::create("tr");
tr.a = dut_if.a; // 采集 DUT 输入 a
tr.b = dut_if.b; // 采集 DUT 输入 b
analysis_port.write(tr); // 将交易数据发送给分析端口
end
endtask
endclass

输出监控:

class output_monitor extends uvm_monitor;


`uvm_component_utils(output_monitor)

// DUT 接口
virtual adder_if dut_if;
uvm_analysis_port #(my_transaction) analysis_port; // 分析端口

function new(string name = "output_monitor", uvm_component parent);
super.new(name, parent);
endfunction

// 运行阶段
task run_phase(uvm_phase phase);
forever begin
@(posedge dut_if.clk); // 等待时钟上升沿
my_transaction tr = my_transaction::create("tr");
tr.expected_sum = dut_if.sum; // 获取 DUT 输出 sum
analysis_port.write(tr); // 发送到分析端口
end
endtask
endclass

Compare:

class my_scoreboard extends uvm_scoreboard;


`uvm_component_utils(my_scoreboard)

uvm_analysis_imp #(my_transaction, my_scoreboard) input_analysis_imp;
uvm_analysis_imp #(my_transaction, my_scoreboard) output_analysis_imp;

my_transaction expected_tr, actual_tr;

function new(string name = "my_scoreboard", uvm_component parent);
super.new(name, parent);
input_analysis_imp = uvm_analysis_imp #(my_transaction, my_scoreboard)
::create("input_analysis_imp", this);
output_analysis_imp = uvm_analysis_imp #(my_transaction, my_scoreboard)
::create("output_analysis_imp", this);
endfunction

// 输入数据分析
function void write(input my_transaction tr);
expected_tr = tr;
expected_tr.expected_sum = expected_tr.a + expected_tr.b; // 参考模型
endfunction

// 输出数据分析
function void write(output my_transaction tr);
actual_tr = tr;

// 比较 DUT 输出和参考模型的期望值
if (actual_tr.expected_sum !== expected_tr.expected_sum) begin
`uvm_error("Mismatch", $sformatf("Expected: %0d, Got: %0d",
expected_tr.expected_sum, actual_tr.expected_sum));
end
endfunction
endclass

2.1.8:位流验证

那对于位流验证,UVM是如何使用的呢?

1:首先,必须准备好你的FPGA的EDA软件(准备好运行时需要的 Flow 的tcl命令)。给出你的芯片仿真时需要的Primitve仿真库。

2:针对你要测试的全芯片或者部分tile,选择你要测试的设计用例(需要有一定的代表性噢,可以是N多,需要有一定覆盖度),用 flow 生成仿真用的门级网表文件,并输出用例的route结果,输出最终的bitstream。

3:开始对要测试的用例,编写参考模型(也是另外一种实现方案)。

4:编写激励(测试)程序,提供相应的激励数据序列。

5:在TestBench上,针对 DUT 的 RefModel模型进行仿真,验证两者输出是否一致,如果一致,说明位流测试正常。比较的方法,要看测试用例的功能。

6:如果测试不正常,可以利用中间输出,日志输出,波形输出等信息进行定位,查看出错原因。

e5babb82-201e-11f0-9310-92fbcf53809c.png

好了,那UVM框架是如何实现的呢?有什么支撑平台和工具吗?

1.2:支撑

那UVM这种框架是如何通平台来支撑它的呢?我们以Synopsys的VCS为例,来说明它是如何支持的(当然,也可以使用Mentor提供的QuestaSim)。

1.2.1:工具

VCS(Verlog Compiler Simulator)是业界领先的仿真工具,原生支持UVM,它提供了一系列的工具和功能,全而覆盖了UVM测试平台中的各项工作。

UVM 组件 VCS 支持工具/功能
Sequence SystemVerilog 编译器直接支持 UVM sequence 的随机生成和调试。
Driver 通过 VCS 的时钟精确仿真,支持 UVM driver 精确地驱动 DUT 信号。
Monitor UVM 信号分析器,与 DVE 图形工具集成,监控信号流。
Compare
Scoreboard
与覆盖率分析工具集成,支持寄存器覆盖率和功能覆盖率的检查。
Debug 提供图形化的 UVM Phase 调试工具,支持动态调试和波形交互分析。
Verification 集成 DVE 和 Verdi 工具,查看波形和调试测试平台的运行时行为。

基于VCS的功能,要实现UVM平台,还需要封装一些标准的命令,达成常见的功能。

1.2.2:平台

为了实现UVM的基础功能,我们需要提供一些封装功能,我们称之为平台。因为VCS并不是直接针对UVM的,所以,我们需要针对它做一些封装,然后我们基于封装来使用,这样,看起来就更像是一个针对UVM实现的平台了。

基本功能如下:(封装方法可以使用Python或其它脚本语言来实现)

平台初始化:

确认 测试平台的主目录,测试工程目录,测试用例目录,工具目录,输出目录……

设置重要参数:

测试的代码列表库

测试用例的分组

运行次数

是否调试模式:提供更多log输出

提供随机种子数:用于控制输入参数的随机种子,控制测试数据的生成。

……

编译/构建:

我们的testbench的代码还是相对比较复杂的,另外,它也依赖于背后的仿真平台提供的大量的库文件,所以,我们一般需要对testbench的代码进行构建,输出各种我们需要的环境。

首先要对DUT代码进行编译,一般是SystemVerilog代码。

一般会使用 Makefile,需要编写相应的makefile,主要是需要将用到的UVM的动态库和引用资源进行构建。VCS有一些针对UVM的支撑库。

仿真:

直接调用VCS的仿真,有低功耗的仿真模式可选

波形分析:

输出波形,用于Verdi波形调试

代码覆盖率统计:

统计测试的代码覆盖率

……

1.2.3:运行

在运行期,为了保证示例可以并行执行,一般会使用HPC集群环境。我们可以使用LSF集群管理,通过 bsub 来将相应的任务,提交到HPC中运行。

比如:

‘一般会把任务分为多条,按顺序将任务放入同一个队列,保证先后次序

bsub -n 1 -M 20480 -q dv_test -Is "上面封装的命令,完成编译或仿真或波形分析的功能"

以上是运算支撑最基本的要求。详细的实现,我们后面会展开给个实例来讲。

二:位流验证

对于位流验证,我们今天要讲的主要是 FPGA的EDA工具测试,在EDA工具的Flow已基本成形的情况下,就可以开始搭建位流验证平台了,用于回归/验证EDA工具的功能。

2.1:流程图

e5ce7960-201e-11f0-9310-92fbcf53809c.jpg

我们先来解释一下上面的典型流程:

测试用例RTL文件

使用FPGA的器件的用例。测试用例文件,一般是DeviceModel提供的一些适合于验证功能的标准用例。作为待测用例。(这些用例,一般是由简到繁)

EDA Flow

FPGA的软件工具的运行flow,在自动化运行时,一般是采用无界面的tcl命令来执行。

这里需要保留多个输出:

综合/映射后的网表:这是针对所有Primitve的电路实现,可以理解为罗列出,我们的设计最终实际用到了哪些逻辑的实例。就是可以看到设计最终使用的Instance,有明确的标识名称。

Route后输出的路由文件:这个用来定位所有实例Instance在芯片中实际的物理位置。也就是Impl后,实际上物理芯片上使用的逻辑块和相应的布线。结合上一步的输出,可以明确查到实例具体的位置,以及走线的路径。

Bitstream 位流:这个是生成的bitstream,这个作为Dut的输入,直接加载到测试平台(如:VCS),加上提前准备好的芯片的原生的仿真库,仿真平台可以实际的模拟芯片的运行,并且得到相应的运行中结果和中间输出。

用例的TestBench

根据实际情况,生成的tb文件。包含激励,定位,比较的逻辑。

测试用例表:原始的测试用例

Primitive行为模型:明确这个Primitive的行为是什么,在寻找参考模型时,需要找到对应的参考实现。

解析输入/输出管脚:找出输入IO 和 输出IO,这个可以在Route 中找到。

编写用例参考模型:根据Primitive的行为和你的设计用例,写等价的功能。注意,这里的等价模型,一般是仿真平台直接执行出结果(并不是基于FPGA的逻辑电路来执行)。

设计输入的激励信号:设计测试的输入数据和相应的序列。

编写比较函数:看如何比较两者的输出。对于返回值 ,可以简单比较输出。对于时序,可能需要检查波形,一般是选择几个关键的点,不可能全部检查。

位流测试平台

结合位流文件,仿真库,testbech ,使用UVM平台进行实际的运行。完成代码的编译,构建,仿真,结果比较的功能。

测试结果

实际比较结果,将结果输出到指定位置,并形成报告。

对于失败的报告,还可以通过查看其它输出(日志,波形等),具体进行问题定位。

对于覆盖度的统计,可以查看目前回归用例的覆盖度,进而逐渐提升。

2.2:验证的问题

如果2.1验证出问题,那可能有哪些问题呢?我们可以看看。

文件的问题
可能是测试用例的问题,route输出的问题(net丢失之类),postmap输出的问题……

IOPackage的问题
可能是IO Pad的错误,这可能是IO Package的问题。可能是输入Pad,也可能是输出Pad不对。IO配置不对,配置信号不对,绑定约束的处理问题。

路由的问题
提供的switch box 的连接不对。

逻辑单元不对
模块的配置有问题,配置问题导致功能出错,模块到Switch box的连线问题

其它
DeviceModel建模的问题,也有可能是Primitive实现的问题(硬件方面的)

具体的定位,可以通过源代码,PostMap文件,route文件来查到具体的实例,然后在VCS的仿真器上,查看具体时点的输出,这里可能是需要使用工具查看波形。

route文件,postmap文件(这个一般是打平的flattern文件)的具体格式就不方便给出样例了,这个每家FPGA的格式会有所不同。

三:FPGA芯片验证方法

我们设计出来的FPGA芯片,是否能满足预期。我们要保证我们提供给用户的FPGA上每一个器件的功能是符合预期的,也就是单个tile的功能,以及Tile之间的连接,整体芯片的逻辑是完全正常的。

所以,我们需要针对单Tile,多Tile,fullchip做位流验证。方法就是使用上面的位流验证平台。针对这三种方法,我们分别来说明,说明应该如何设计样例 ,来达成相应的结果。

3.1:单Tile位流验证

对于每一种Tile做单独的测试(所有的Primitive),比如:CLB(LUT,CLA,DFF,SFTR……),CMT,IO,DSP,BRAM,EMRAM,FIFO,OBUF,IBUF,IOBUF,……

并且也包括Tile内部的连接信号路由的验证。

我们以CLB为例:

对于CLB,里面主要涉及不同的LUT,DFF,CLA,SFTR,需要设计一系列的用例,去覆盖相关的器件使用。

我们以最简单的 Lut2为例,来看看如何构建测试用例,参考用例,激励数据,结果比较。

3.1.1:CLB —— LUT2

首先,我们要了解Lut2的原理,它是由2输入1输出组成,可以完成 2个单bit输入1个输出的任何逻辑。比如:a & b,a | b , a xor b。

一般来说,厂商会提供 LUT2的Primitive IP,我们假如提供的IP就叫做 YY_LUT2。

那么,对于Dut,那就很简单了。注意 a & b 的真值 表是 1000b 也就是 h8

Dut的设计代码:

moudule And2(

input a,

input b,

output result

);

YY_LUT2 #(.INIT(4'h8)) lut2(.Io(a), .I1(b), .O(result));

end module

将该代码使用 eda flow 执行,生成 bitstream。

我们来看一下参考用例的写法:

module RefModel(input A,

input B,

output Y);

assign Y = A & B ; // 参考模型的布尔函数

endmodule

以上的代码,仿真工具在运行时,会在每个仿真周期,根据输入数据的变化来重新输出结果。对应的逻辑表达式的运算是在仿真器中执行(实际上就是语法解析,然后交给CPU来执行了)。

当然,你的示例还可以是 A | B,A xor B,若干的样例。

另外:

INIT=0 IS_C_INVERTED = 0 IS_CLR_INVERTED=1 可以验证 DFFCE 的功能

1bit加,1bit 减 可以验证CLA功能

wclk极性不反转 验证 SFTR32

将INIT、IC_C_INVERTED、IS_PRE(CLR/R/S/)_INVERTED的值进行随机,inst约束到FFA0 验证 LPQCE

3.1.2:DSP

我们再以DSP为例,选择合适的用例(针对DSPX18 的 2个输入乘法)

直接调用 YY_DSP48_CPLX18 ,具体就不写了。

具体如何设置用例,需要根据DSP48_CPLX18的输入参数来设置,尽量保证相关的参数可覆盖。

3.2:多Tile位流验证

需要验证 Tile间路由的正确性,在多个tile分配资源,全局信号,时钟可以正常共享,跨tile的优化结果符合预期。主要是对一组tile,某个功能区域进行验证。验证多个tile的功能及其之间的交互。可以用来验证协同工作,比如:DSP 与 BRAM的协同工作情况,验证范围有限,无法覆盖全芯片的全局资源,比如:时钟网络,全局布线等。

需要构造如下用例:

长路径信号传输:

Tile间级联:多个tile之间的逻辑级联(比如:多级加法器)

Tile内外通信:在不同Tile实现的模块之间进行通信(如:FIFO,AXI总线)

3.3:全芯片位流验证

对于全局资源(如:时钟,全局线)的使用进行验证。关注边界行为(I/O引脚,DDR,PCIe)。

需要构建的用例 :

设计一条覆盖尽可能多Tile的信号路径,从一个边界Tile传播到对角线另一侧。

在设计中启动全局时钟。

包含外部接口(I/O,DDR,PCIe)在设计中。

选用的用例,一般会是一些经典的电路设计,比如:FPGA一般会和闪存配合使用,那我们就选用一些标闪的闪存器件来搭建用例(因为闪存用例是有公开的行为模型和仿真库的)

因为是针对整个芯片的测试,所以,激励数据,应该采用jtag方式输入,涉及到PRAM的操作。相对比较复杂,这里不再展开细说。

3.4:代码的测试覆盖率

测试是否有效,主要看覆盖率,所以,在仿真运行中输出测试覆盖率,是非常重要的指标。

覆盖率报告通常包括以下信息:

总体覆盖率

显示整个设计的总体覆盖率(如行覆盖率、分支覆盖率等)。

模块级覆盖率

显示每个模块的覆盖率详情。

代码行覆盖率

显示每一行代码是否被执行。

分支覆盖率

显示每个分支是否被覆盖。

条件覆盖率

显示每个布尔表达式的条件组合是否被覆盖。

状态机覆盖率

显示状态机的所有状态和状态转换是否被覆盖。

翻转覆盖率

显示信号是否发生了 0 到 1 或 1 到 0 的翻转。

代码覆盖度能够查看测试的完整度。是非常重要的参考指标。

最后我们来看看,要搭建一个自动化的验证平台,需要做一些什么样的工作:

这部分是一个封装动作,和验证本身的关系并不是很大,但如果对验证的细节不清楚,也不能搭建一个好的,可扩展的平台,因为平台的功能也不是一成不变的,需要有一个演进的过程。如果有好的设计,自然最佳。

四:位流验证的自动化平台

4.1:平台架构

e5e10256-201e-11f0-9310-92fbcf53809c.jpg

这软件EDA的位流验证的架构。如果验证是上板验证(生产测试中心)。那位流的运行就不是在仿真环境,而是在板上的物理芯片运行,然后想办法把物理芯片的运行结果,按时序取回,然后进行对比。

4.2:资源管理

需要管理的资源:

平台的代码

主要是流程控制的代码,Python,Shell脚本,主要是存放到Git中,应该需要管理版本,

一般会是解释性脚本语言,不会有编译/构建的过程。

测试工程

每一次回归测试,我们定义为一个工程。而工程会描述所有运行的输入,输出。

工程的定义:针对某个芯片,某种验证方式,某个器件的测试,我们认为是一个验证工程。

待验证芯片——芯片的系列(架构),具体输出的芯片版本号(锁定的版本)

待验证的内容—— FullChip,或者 TILE_CLB_LUT2,或者 BRAM & DSP 的联合工程。

对应的仿真库——不同验证点,需要提供不同的仿真库,比如 fullchip和单tile需要的仿真库是不同的。但相对固定,基本上是提前准备好的。但是如果芯片的架构发生变化,需要做相应的更换。也可以理解芯片系列的版本发生变化。

对应的待测式DUT——待测试的DUT的测试用例。

DUT 对应的RefModel—— 对应的参考模型。

相关的配置信息——可能存在一些配置,可能待测内容不同,配置会有所不同。略

输出目录——包括位流输出目录(包括一些中间文件输出),最终输出目录。

DUT Testbench

每个待测工程,都需要有一个TestBench 代码,TestBench 用来定义整个测试的过程。包括如何使用生成的位流进行仿真运行,如何调用RefModel(Golden case)获得结果,两者如何进行比较,如何输出。

注意,不同测试工程,可能代码会有所不同。

测试用例

测试用例是针对芯片待测单元的调用。可能需要覆盖待测单元的大多数输入组合。这些用例需要进行统一管理,在需要时,在测试工程中配置。

比如:针对 LUT1的测试用例 (只需要初始化一下真值表即可)

YY_LUT1 # ( INIT (2'h3) inst_lut1() // o = a

参考模型代码

针对测试用例,与之对应的另外一种实现(不依赖于FPGA),直接在VCS中运行。如果需要考虑时序,该模型代码需要打拍。

比如:assign o = a 就是针对上面的LUT1用例的Golden case。

其它配置

配置EDA工具的运行环境,这个是可以按需配置,因为对于EDA,研发每天都会有新的版本。

4.3:调度平台

因为需要自动化,必须要有调度,这样可以定时自动执行。

可以通过脚本控制执行的入口和过程,控制超时时间,控制运行的队列(串行还是并行),可以将大任务发到计算集群。

调度很简单,一般使用 Jekins的 Pipeline即可,Jekins支持Shell,可以进行任务的编排。

4.4:位流生成

位流生成,就是使用j最新EDA和相应的flow tcl ,用来生成位流。

位流生成需要注意几个点:

可能会添加固定的物理约束,简化输出,明确实际的 IOPAD。

4.5:仿真运行

对于test bencch 运行,会有多个步骤。

激励数据的处理

这里要看一下,是否需要形成有针对性的激励数据。可能和位置转换有关(实际位置可以通过位流输出的 instance和 route信息,获取实际的位置信息)。

test bench 代码编译

针对 test bench代码,建议采用makefile进行编译/构建,这样比较容易针对VCS进行动态链接和引用,也定义输出的动作。

test bech 仿真运行

使用仿真平台,输入激励,进行仿真,输出波形,输出代码覆盖度。

对Golden Case 进行运行,输入激励,执行输出。

两者进行比较,在仿真log中输出

4.6:结果输出

收集结果,确认是否成功,输出最终报告。

可能还会输出一些必要的数据,波形,代码覆盖度之类。

五:其它

5.1:硬件设计验证

对于硬件部的位流验证,实际上基本上是一致的。不同之处主要有:

1:在EDA的位流生成功能不成熟前,需要有其它方式生成位流。

2:硬件验证不通过的情况,会关注硬件本身的设计,而不是位流的生成。关注点会有所不同。

5.2:生产测试中心位流验证

对于生产测试中心,需要实际上板测试。所以。

1:位流需要download到实际芯片上运行,激励需要实际输入到芯片。

2:参考模型与软件一样,但注意,大多数时候要考虑时序,而不是简单的组合逻辑。

3:对于实际芯片的运行输入/输出,一般需要做特殊处理,比如:设计专用电路,完成激励输入,设计驱动程序将输出数据写入本地磁盘,然后通过磁盘文件获取结果,进行比较。

输出的文件需要表达时序信息。

4:生产测试发现问题,关注的是硬件的可靠性。

原文链接:https://community.sslcode.com.cn/6789d33a59bcf8384aa65e71.html

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FPGA
    +关注

    关注

    1646

    文章

    22060

    浏览量

    619165
  • 芯片
    +关注

    关注

    460

    文章

    52566

    浏览量

    441869
  • eda
    eda
    +关注

    关注

    71

    文章

    2939

    浏览量

    178224
  • 数字电路
    +关注

    关注

    193

    文章

    1641

    浏览量

    81978

原文标题:FPGA EDA软件的位流验证

文章出处:【微信号:gh_9d70b445f494,微信公众号:FPGA设计论坛】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    验证中的FPGA原型验证 FPGA原型设计面临的挑战是什么?

    和性能。? 由于硬件复杂性不断增加,需要验证的相关软件数量不断增加,因此它今天的使用范围更加广泛。? 为什么公司使用FPGA原型?? FPGA已经被用于
    发表于 07-19 16:27 ?2201次阅读

    设计与验证Verilog HDL FPGA设计与验证的好书

    本帖最后由 eehome 于 2013-1-5 10:01 编辑 EDA先锋工作室的精品书籍,国内少有的系统讲述FPGA设计和验证的好书,特别是验证部分很精华,现在和大家分享,同
    发表于 08-02 14:54

    FPGA设计的仿真验证概述

    仿真验证概述本文节选自特权同学的图书《FPGA设计实战演练(逻辑篇)》配套例程下载链接:http://pan.baidu.com/s/1pJ5bCtt 仿真测试是FPGA设计流程中必不可少的步骤
    发表于 04-10 06:35

    基于EDA技术的FPGA该怎么设计?

    对传统电子系统设计方法与现代电子系统设计方法进行了比较,引出了基于EDA技术的现场可编程门阵列(FPGA)电路,提出现场可编程门阵列(FPGA)是近年来迅速发展的大规模可编程专用集成电路(ASIC
    发表于 09-03 06:17

    基于EDA技术的FPGA该怎么设计?

    物联网、人工智能、大数据等新兴技术的推动,集成电路技术和计算机技术得到蓬勃发展。电子产品设计系统日趋数字化、复杂化和大规模集成化,各种电子系统的设计软件应运而生。在这些专业化软件中,EDA
    发表于 10-08 08:02

    EDA软件的安装与配置(仅针对开发Altera FPGA)

    公欲善其事,必先利其器。一个良好的EDA开发环境,是您开发FPGA以及nios的得力助手。但不少朋友在安装、配置EDA软件环境的过程中,就遇到一些麻烦;所以本人就写了如下一点文字
    发表于 07-20 09:28 ?67次下载

    EDA Tools in FPGA

    EDA Tools in FPGA用于开发FPGAEDA工具:随着集成电路和计算机技术的发展,越来越多的公司不断的开发出更加好用的EDA
    发表于 12-05 16:10 ?0次下载

    常用EDA软件介绍

    6.1 Synopsys EDA软件6.2 Cadence EDA软件6.3 Tanner EDA软件
    发表于 09-03 20:48 ?164次下载

    基于多种EDA工具的FPGA设计

    基于多种EDA工具的FPGA设计 介绍了利用多种EDA工具进行FPGA设计的实现原理及方法,其中包括设计输入、综合、功能仿真、实现、时序仿真、配置下载等具体内容。并以实
    发表于 05-14 18:38 ?1001次阅读
    基于多种<b class='flag-5'>EDA</b>工具的<b class='flag-5'>FPGA</b>设计

    芯片设计EDA软件的使用

    什么是 EDA 软件 EDA(Electronic Design Automation)是电子设计自动化软件的简称,EDA 产业是集成电路设
    的头像 发表于 10-30 13:30 ?2934次阅读

    什么是板级EDA软件 eda器件分几类 数字EDA和模拟EDA的区别

    板级EDA软件(PCB EDA软件)也是一种电子设计自动化(EDA软件,它是用于电子电路设计中
    发表于 05-03 05:42 ?7684次阅读

    使用加密和身份验证来保护UltraScale/UltraScale+ FPGA比特

    电子发烧友网站提供《使用加密和身份验证来保护UltraScale/UltraScale+ FPGA比特.pdf》资料免费下载
    发表于 09-13 17:14 ?1次下载
    使用加密和身份<b class='flag-5'>验证</b>来保护UltraScale/UltraScale+ <b class='flag-5'>FPGA</b>比特<b class='flag-5'>流</b>

    原型平台是做什么的?proFPGA验证环境介绍

    proFPGA是mentor的FPGA原型验证平台,当然mentor被西门子收购之后,现在叫西门子EDA
    的头像 发表于 01-22 09:21 ?2539次阅读
    原型平台是做什么的?pro<b class='flag-5'>FPGA</b><b class='flag-5'>验证</b>环境介绍

    智多晶EDA工具HqFpga软件实用小功能

    智多晶EDA工具HqFpga软件实用小功能增加啦,支持生成可调用网表的功能和ballmap功能。下面来给大家讲解一下如何通过HqFpga软件
    的头像 发表于 12-05 10:23 ?1194次阅读
    智多晶<b class='flag-5'>EDA</b>工具Hq<b class='flag-5'>Fpga</b><b class='flag-5'>软件</b>实用小功能

    华大九天物理验证EDA工具Empyrean Argus助力芯片设计

    在芯片设计的片之路充满挑战,物理验证EDA工具无疑是这“最后一公里”关键且不可或缺的利器。它通过设计规则检查、版图与原理图一致性验证等关键流程,为IC设计契合制造需求提供坚实保障。作
    的头像 发表于 07-03 11:30 ?1472次阅读
    华大九天物理<b class='flag-5'>验证</b><b class='flag-5'>EDA</b>工具Empyrean Argus助力芯片设计