• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

SOC/IP验证工程师

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

SOC验证C代码中如何打印字符串?

学过C语言都知道,在程序中添加打印信息有助于我们追踪程序执行的情况。特别是debug的时候,打印一些log信息对快速定位到问题非常有帮助。
怎么在SOC验证的C代码中打印字符串呢?用printf ?
我们来试一下:

执行结果:

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

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

puts 又跳到 _puts_r ,依次下去,由printf 编译出了一系列的指令代码。由于CPU最终综合成版图,因此在CPU的RTL代码中不会存在读到某条指令打印一个字符串的功能。所以单纯的调用printf 并不会在log中打印字符串信息。
如何实现打印?
两个思路,第一个思路,在SOC的TB里面增加一个CPU bus的monitor,我们在monitor中实现一个功能,当看到特定地址,特定数据的时候,开始收集要打印的字符串,当看到特定地址,另外一个特定数据的时候,结束字符串的收集,并将收集到字符串打印。
以下是我们在一个project中看到特殊数据 24’hdddd_11xx 开始收集字符串。

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

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

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

Hello World 打印出来了。
我们再看看 puts编译后的代码是什么?

这次 puts并没有跳转到 _puts_r ,而是向特定地址发送特定数据表示开始,然后传输字符串,并以特定数据结束。当我们的monitor检查到这些特殊的数据时就会打印出log信息。
上面打印的方式可以解决在SOC验证环境中打印 字符串的问题,但是在芯片流片回来之后,在C中调用上述函数还能打印吗?显然是不可以的,因为这个时候外部的monitor都没有了,更别说不能综合的display函数等。
下面介绍一种更加普遍的使用方法。我们在嵌入式硬件开发的过程中经常用到串口调试工具。
因此在我们SOC验证环境中集成UART的slave device,在UART device收到数据后,打印出字符串信息是一个很好的选择。
为此,我们通过向uart device写字符串的形式,然后在UART device中实现打印功能。

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

下面是执行效果

同样实现了打印,而且这种打印方式在后续芯片流片回来之后可以通过串口调试 查看打印的信息。
看到这里,大家明白怎么在SOC中实现字符串打印了吧。

posted on 2023-05-20 14:23  SOC验证工程师  阅读(638)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3