磨刀不误砍柴工:开发Model,辅助设计DUT

论开发Model对设计DUT的重要性

最近在设计一个模块。
时间紧,任务重。一开始,觉得为了节约时间,没有先开发Model,直接去写DUT。

整个模块分成三部分。
在分别完成三个部分时,由于并不十分复杂,故都是手算的计算结果,然后验证DUT的功能。

但是在三个模块一起联合调试时,由于前期理解不充分,设计需要修改,然后计算结果就变了,造成之前手算的结果报废。

如果重新手算,就增加了不少的工作量,而且,感觉这都是重复低效的工作量。

怎么办?

决定给各个模块添加C语言写的Model。
优点:一劳永逸,类似UVM那样,直接去比较Model与DUT的输出,不用每次都要人工去计算比对。
缺点:需要暂停调试DUT,改而研究如何开发一个Model,并自动对比,之前完全没有做过类似工作,不知道需要花多少时间,能否成功,心中没底。

为了一劳永逸,决定还是干!

下面是实现的主要模块。

主要的工作内容

主要分两步:

一、

首先用C语言写一个Model,能够正确执行DUT需要的功能。这个的开发比较快,因为采用的高级语言,有许多的库函数可以用,而且高级语言比较灵活,自由度大,开发速度快。这个都还比较快。

二、

接下来才是难点。
如何将C语言写的Model与SV写的DUT联合起来,进行结果的check?

经过几天的折腾,自己百度加请教同事,总算解决了。
下面来说说重要的地方。

1、Check Module

对比DUT与Model的结果,单独写一个Module来完成check功能。

Module check(
// module的输入信号来自DUT
input       clk,
input       resetn,
input       start,
input       valid,
input[15:0]   result
);
... ...
import "DPI-C" context task c_model(output bit[15:0] ref_data[10000]);//引入Model,从接口上得到参考结果
bit[15:0]   ref_data[10000];//声明一个足够大的数组信号来存放来自Model的参考结果
logic[31:0]   cnt;
... ...

// 假设start信号是DUT开始计算的信号,而Valid信号是DUT输出有效的信号,因为DUT需要一定周期去计算出结果,所以start信号必定比valid信号早很多个周期到达。
// 这里为了简单,假设start的信号只是一个周期有效 

// 当start有效时,就从Model计算得到参考结果
always @(posedge start) begin
    ref_data(ref_data);//从Model得到参考结果,一般Model计算都很快,当作一个周期就计算完成就行了
end

// 下面是去检测valid信号,当valid有效,就去对比DUT结果与参考结果的值
always@(negedge clk or negedge resetn)begin
    if(!resetn) begin
        cnt <= #1 0;
    end
    else begin
    if(valid) begin
        if(result != ref_data[cnt]) begin
             $dispaly("%t, ERROR cnt = %d, dut = %x, ref_data = %x", realtime, cnt, result, ref_data[cnt]);
        end
        cnt <= #1 cnt + 1;
    end
    end
end


endmodule

以上是一个简单的check。
思路:从DUT得到开始信号和结果信号,然后在DUT的输出有效时,就去比较DUT与Model的结果,如果不一致,就打印出来。

注意:必须在DUT的结果到来前就计算完Model。Model的计算非常快,可以当作不花时间。

为了保持结果的一致性,最好是Model和DUT读取相同的输入文件获取输入数据,避免因为输入数据的不同造成的错误。

2、Model

上面用到了Model。
可以看到,DUT的输出是一串数据,可以看作是数组一样。
Model将计算结果通过函数接口传递出来。

#include “svdpi.h”  // 必须要引用这个头文件,代表SV与C语言之间的交换接口

... ...
// 这是Model的顶层
int c_model( int* ref_data)//接口上的输出变量;
//注意,这是指向数组的指针,而且,数据必须是32位的;
//如果是16位的,那么在DUT中就只有偶数地址的数据,奇数地址的数据就找不到,数据的个数也跟着减半。
//具体原因暂时没有找到,猜测C语言的数据在内存中的存储最小单位是word吧,猜测的,不确定。
{
 ... ...
int cnt = 0;
...
xxx = ...
cnt++;
...

// 当计算完成后,结果通过输出接口传递给DUT
*(ref_data+cnt) = xxx;

return 0;
}

到此,就可以愉快得监测DUT与Model的结果并对比,自动报错,方便调试,而且可以随意修改输入数据,形成不同的激励。

好用!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值