怎么在SOC验证的C代码中打印字符串呢?用printf?

电子说

1.3w人已加入

描述

学过C语言都知道,在程序中添加打印信息有助于我们追踪程序执行的情况。特别是debug的时候,打印一些log信息对快速定位到问题非常有帮助。

怎么在SOC验证的C代码中打印字符串呢?用printf ?

我们来试一下:

gcc编译器

执行结果:

gcc编译器

没有出现 Hello world。这种结果是符合预期的。C code 通过GCC编译生成bin文件然后送到CPU中按指令进行执行。我们看下这段代码编译出来的指令是什么?

gcc编译器

这里 printf 编译出来是jump到一个puts的函数里面。puts函数又是什么呢?

gcc编译器

puts 又跳到 _puts_r ,依次下去,由printf 编译出了一系列的指令代码。由于CPU最终综合成版图,因此在CPU的RTL代码中不会存在读到某条指令打印一个字符串的功能。所以单纯的调用printf 并不会在log中打印字符串信息。

如何实现打印?

两个思路,第一个思路,在SOC的TB里面增加一个CPU bus的monitor,我们在monitor中实现一个功能,当看到特定地址,特定数据的时候,开始收集要打印的字符串,当看到特定地址,另外一个特定数据的时候,结束字符串的收集,并将收集到字符串打印。

以下是我们在一个project中看到特殊数据 24’hdddd_11xx 开始收集字符串。

gcc编译器

以下是我们在一个project中看到特殊数据 24’hdddd_eeee 时打印字符串。

gcc编译器

这样,我们可以在c里面实现一个打印字符串的函数。

gcc编译器

通过上面这种手段,我们巧妙的将C语言的打印和 verilog的 $display 打印连接起来。我们来看看效果

gcc编译器

Hello  World 打印出来了。

我们再看看 puts编译后的代码是什么?

gcc编译器

这次 puts并没有跳转到 _puts_r ,而是向特定地址发送特定数据表示开始,然后传输字符串,并以特定数据结束。当我们的monitor检查到这些特殊的数据时就会打印出log信息。

上面打印的方式可以解决在SOC验证环境中打印 字符串的问题,但是在芯片流片回来之后,在C中调用上述函数还能打印吗?显然是不可以的,因为这个时候外部的monitor都没有了,更别说不能综合的display函数等。

下面介绍一种更加普遍的使用方法。我们在嵌入式硬件开发的过程中经常用到串口调试工具。

通过简单的几根线与电脑连接,然后用串口调试助手就能将SOC和电脑调试界面连接起来。

gcc编译器

因此在我们SOC验证环境中集成UART的slave device,在UART device收到数据后,打印出字符串信息是一个很好的选择。

为此,我们通过向uart device写字符串的形式,然后在UART device中实现打印功能。

gcc编译器

我们来测试下用上面这种方式打印的效果,prints 是我们向uart 发送字符串的函数。

gcc编译器

下面是执行效果

gcc编译器

同样实现了打印,而且这种打印方式在后续芯片流片回来之后可以通过串口调试 查看打印的信息。

看到这里,大家明白怎么在SOC中实现字符串打印了吧。





审核编辑:刘清

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

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分