路科验证的个人空间 https://blog.eetop.cn/1561828 [收藏] [复制] [分享] [RSS]

空间首页 动态 记录 日志 相册 主题 分享 留言板 个人资料

日志

SV与UVM接口应用篇之七:将Matlab算法模型嵌入UVM环境

已有 2646 次阅读| 2019-11-27 12:01 |个人分类:验证系统思想|系统分类:芯片设计

rockeric.com

在 SV及UVM接口应用篇之四:Matlab及Simulink模型与UVM的混合仿真 一文中,我们谈到的是利用Matlab提供的C函数接口来在后台启动Matlab的引擎继而直接执行M算法模型函数。在执行过程中,M模型函数传递也可以通过C一侧映射的数据类型,由C一侧传入以及获取最终的数据运算结果。

实际上,这种运行方式也可以变得复杂起来,例如由C一侧调用Matlab提供的系统函数接口,不再只是单纯地启动Matlab引擎,还可以将部分或者全部以往由M实现的函数处理功能转而由C函数去实现。这种更深入的交互方式可以在Matlab官网给的实例中获得详尽内容,也有不少的Matlab教材在讲与C互动的部分中有讲解。

https://ww2.mathworks.cn/help/

https://ww2.mathworks.cn/help/matlab/calling-matlab-engine-from-c-programs-1.html

只是在实际中,我们发现,对于Matlab算法模型的验证对于Matlab工具的依赖性并没有那么多。意思是说,往往这些模型在Matlab环境开发的时候就已经稳定了,而将它们代入到C环境继而到UVM环境中时,我们不再需要做额外的只有Matlab才能提供的数据处理。简而言之就是,我们希望通过保持算法功能的条件下,让Matlab算法模型先转化为C模型,继而在UVM中通过DPI-C直接对C模型进行调用。调用的方式也不会有什么变化,即给转化以后的C模型传入大量的数据,接下来交由C模型进行运算,最后再将C模型的运算结果交给UVM,作为参考数据,用以后来与RTL模型输出数据的比对。

选择这样处理M模型有一些明显的优势:

  • 通过Matlab提供的转换方式,可以将M函数“无损”地转换为C函数。

  • 这种转换方式使得接下来在调用C模型时,不再需要像之前一样在后台启动Matlab引擎,可以间接降低仿真对于联合仿真的多语言之间的同步要求和性能损耗(Matlab引擎在后台运行消耗更多资源)。

  • 将原本需要的UVM-C-Matlab的语言同步接口问题简化为UVM-C的典型DPI-C问题,更加便于调试。


接下来,我们就这一种方法给出一个示例,希望对于那些遇到了类似Matlab算法模型验证问题的同学可以提供一些参考。关于本文的示例代码,大家也可以通过【阅读原文】,在路科的官网下载这个小例程。


我们这里提供了一个对数组进行简单处理的M函数mtfun。

function tch_out = mtfun (tch_in) %tch_in = [1;2;3]; fprintf('Matlab function mtfun:: tch_in data \n'); fprintf('%d \n', tch_in); tch_out = [tch_in;tch_in;]; fprintf('Matlab function mtfun:: tch_out data \n'); fprintf('%d \n', tch_out);end


这个函数的功能即是增长作为输入参数的数组,例如,如果tch_in是[1;2;3],那么输出结果即为[1;2;3;1;2;3]。用这个一个简单的函数来模拟算法模型常常会对输入的多个数组进行处理,接下来将运算结果也作为数组输出的场景。
按照本节处理M模型的方式,我们将按照例程中的指导文件README来展开M模型的嵌入流程。
第1步安装Matlab,并且设置有关环境变量,即$LD_LIBRARY_PATH和$PATH。setenv LD_LIBRARY_PATH /opt/MATLAB/R2016a/bin/glnxa64:/opt/MATLAB/R2016a/sys/os/glnxa64:$LD_LIBRARY_PATHset path=(/opt/MATLAB/R2016a/bin $path)alias matlab "/opt/MATLAB/R2016a/bin/matlab"

第2步

在转换M模型之前,需要启动必要的Matlab应用。

mex -setupmbuild -setup

第3步

利用mcc编译器,将M模型编译转换为C的动态库。在这一步,上面的M模型mtfun函数即被转换为C模型,该模型被编译到动态库libmtfun.so中。

mcc -W lib:libmtfun -T link:lib mtfun.m

第4步

可以在C一侧的函数中调用libmtfun中的mtfun函数,这一步是C库之间的调用,已经与Matlab引擎脱离关系。这里我们省略了UVM通过DPI-C接口调用C函数,而主要是在说明,一旦将M模型转换为C动态库,即可实现C域中的函数调用和结果返回。

这里给出了C的“盒子”(wrapper)函数,用来演示,如果调用在libmtfun库中的函数mtfun,并且传入数组,同时得到返回的数组。这一简单示例即能够在接下来被嵌入到UVM环境时,进一步与UVM环境完成数组的传递,最终实现将M模型转换为C模型,最后给套上“盒子”,嵌入到UVM环境中用来做参考模型。

#include <stdlib.h>#include <stdio.h>#include <string.h>#include "mex.h"#include "libmtfun.h"int mtcall(int *cin, int in_size, int **cout, int *out_size) { int i;   mxArray *min, *mout;、 if( ! mclInitializeApplication(NULL, 0) ) { printf("Could not initialized application. \n"); return 1; } if( ! libmtfunInitialize() ) { printf("Could not initialized the library. \n"); return 1;   } min = mxCreateNumericMatrix(in_size, 1, mxINT32_CLASS, mxREAL); // create same size array as C side memcpy((char*)mxGetPr(min), (char*)cin, sizeof(int)*in_size); // copy C array to Matlab array printf("mtlab function call started \n"); mlfMtfun(1, &mout, min); // Call matlab function   printf("mtlab function call finished \n"); printf("mtlab mxarray copy started \n"); *out_size = mxGetM(mout) * mxGetN(mout); printf("out_size = %d \n", *out_size); *cout = (int*) malloc(sizeof(int)* (*out_size)); // allocate M*N sized int array memcpy((char*)(*cout), (char*)mxGetPr(mout), sizeof(int)* (*out_size)); // copy Matlab array to C array printf("mtlab mxarray copy finished \n"); mxDestroyArray(min); mxDestroyArray(mout); libmtfunTerminate(); mclTerminateApplication();}int main() { int *cin, *cout;   int in_size = 5, out_size, i; cin = (int*) malloc(sizeof(int)*in_size); for(i=0; i<in_size; i++) *(cin+i) = 2*i; // input C array initialization   mtcall(cin, in_size, &cout, &out_size); // call C wrapper function printf("mtfun cout result: \n"); for(i=0; i<out_size; i++) { // print C array result printf("cout[%d] is %d \n", i, *(cout+i)); }}


在C盒子函数mtcall中的实现中,这里不再对Matlab提供的C编程接口做详细解释,同学们可以在给出的Matlab技术支持网页中找到所有详细的函数和对应的功能。从应用角度出发,路桑这里给出一些在实现过程中要注意的细节(也是可能掉进的坑):

  • mclInitializeApplicationlibmtfunInitialize这两个函数调用很重要,没有它们,就无法顺利从libmtfun中调用mtfun函数。
  • 在调用mtfun传递数组前,需要使用Matlab提供的创建数组的方式mxCreateNumericMatrix,只有这样,数据形式才能够对应,在C数组和Matlab数组的数据映射处理中,我们分别采用了mxCreateNumericMatrixmemcpy,和malloc
  • 在调用了mlfMtfun(M模型的mtfun函数转换后的C库中的函数名,在libmtfun.h中声明),还需要最后调用mxDestroyArray来释放min和mout所指向的、不再使用的Matlab数组空间。
  • 与启动函数对应的是调用两个终结函数mclTerminateApplicationlibmtfunTerminate,用来结束盒子函数mtcall与mlfMtfun函数之间的数据交换,继而最终释放整个的mltMtfun函数空间。调用这两个函数可以确保盒子函数mtcall在调用之后可以正常退出。


接下来,我们通过在C一侧的main函数来模拟UVM通过DPI-C接口来调用盒子函数mtcall,即传递一些数组和控制变量,接下来通过mlfMtfun的运算,最后将数据结果通过盒子函数传出。


所以第4步需要完成C函数(mtcall,main)与M转换得来的动态库libmtfun.so之间的链接和调用。在该命令行中需要注意的是,有不少需要加载的预定义的Matlab系统函数库,例如-leng -lmx -lmex

gcc -m64 -I/opt/MATLAB/R2016a/extern/include -L/opt/MATLAB/R2016a/bin/glnxa64 -L. -lmtfun -leng -lmx -lmex mtcall.c -o mtcall


第5步为了能够使得在C函数运行时找到libmtfun.so动态库,需要更新环境变量$LD_LIBRARY_PATH。setenv LD_LIBRARY_PATH ./:$LD_LIBRARY_PATH


第6步
即可以调用编译好的可执行对象。
./mtcall


从仿真打印信息中我们可以得到:

  • main函数在调用盒子函数mtcall的过程中,传递了C数组。
  • mtcall在调用mlfMtfun时转换了对应的Matlab类型数组并且传递,在获得了新的Matlab类型数组指针以后,又将内容复制到了新的C数组。
  • 新的C数组最后又被main函数所获取。

mtlab function call started Matlab function mtfun:: tch_in data 0 2 4 6 8 Matlab function mtfun:: tch_out data 0 2 4 6 8 0 2 4 6 8 mtlab function call finished mtlab mxarray copy started out_size = 10 mtlab mxarray copy finished mtfun cout result: cout[0] is 0 cout[1] is 2 cout[2] is 4 cout[3] is 6 cout[4] is 8 cout[5] is 0 cout[6] is 2 cout[7] is 4 cout[8] is 6 cout[9] is 8


在实际项目中,当我们一开始尝试绕过传统的在后台启动Matlab引擎方式的时候,我们服务的客户对此还有过犹豫,他们担心转换后的内容可能有功能偏差,同时也对于大型的Matlab模型在转换后的C函数执行效率低,可能会影响动态仿真时的性能。不过在最后采用了这种新方案以后,仿真性能并没有出现明显的下降,且由于仿真过程中可能会频繁地调用M模型转换后的函数,这种语言接口本身经过优化的DPI-C调用方式也要优于在UVM-C-Matlab之间的数据间接同步方式。


考虑到目前做算法验证的场景越来越多,希望这一篇Matlab算法模型嵌入UVM的应用能够像立秋后的雨一样,带给夏日一些清凉。


SV及UVM接口应用篇之一:DPI接口和C测试(上)

SV及UVM接口应用篇之二:DPI接口和C测试(下)

SV及UVM接口应用篇之三:SystemC与UVM的TLM通信

SV及UVM接口应用篇之四:Matlab及Simulink模型与UVM的混合仿真

SV及UVM接口应用篇之五(终):脚本语言与UVM的交互

SV与UVM接口应用篇之六:开辟后台C服务线程




点赞

评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 注册

  • 关注TA
  • 加好友
  • 联系TA
  • 0

    周排名
  • 0

    月排名
  • 0

    总排名
  • 0

    关注
  • 253

    粉丝
  • 25

    好友
  • 33

    获赞
  • 45

    评论
  • 访问数
关闭

站长推荐 上一条 /1 下一条

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-3-29 23:58 , Processed in 0.015311 second(s), 12 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
返回顶部