ZeBu RISCV工程porting问题记录

最近学习ZeBu的时候尝试使用一个简单的Verilog工程入手,这个简单的工程是一个简化的RISC-V核,里面含有一个SPI Flash控制器,Uart模块,GPIO模块,文件比较少,并且整个工程是可以直接综合的,比较适合入手。

代码Porting的时候想得比较简单,直接写个testbench,把需要的文件列表加进去,跑一跑,结果从综合结果来看memory什么的都可以正常识别,但是直接运行的时候就告诉说是Memory压根就没有例化,这个就比较尴尬了,没有办法,只好在FPGA里面试一下啊,文件列表加到simplify_pro中跑一下,发现几个小时也搞不定呀,又换成Vivado综合跑一遍,直接报错了哇,说是有信号直接多驱动了,信号位于spiflash ip里面,仔细瞧瞧,这个IP只是一个仿真模型,里面确实有很多信号多驱动,不过不明白为什么simplify_pro和zebu编译的时候都不会报错,并且zebu里面还可以直接认出memory。

暂时搞不定spiflash,只好改design,去掉不会玩的spiflash了,去的过程还是比较顺利的,毕竟也比较简单,顺着信号直接往下删就好了,改完的design仿真跑跑,嗯,木有问题,FPGA跑跑,问题多多,在FPGA里面主要碰到以下这么几个问题:

  1. SRAM模型数据不能正常加载,在design中,我们的程序是直接load到SRAM中运行的,不过在FPGA中,这个load的动作($readmemh)似乎没能生效,行为仿真没有问题,后仿真就有问题了,生成bit下载到FPGA里面运行也不正常。
  2. 既然SRAM模型不好用那就换成NGC吧,后面结果告诉我NGC工作是正常的,不过NGC里面有个输出buffer的选项一定要去掉,否则会出现逻辑上的错误,这个在仿真过程中就可以复现,具体是CPU写数据的时候出现问题,这个也是比较奇怪的,感觉上输出buffer应该是影响读数据,可能是写数据的时候CPU也会将数据读回的原因吧。不过好得是NGC可以正常工作了,这里面还牵扯到一个hex文件到coe文件的转换的问题,这两个文件的区别主要还是格式上的区别,coe文件有个固定的文件头,然后数据后面会有个逗号,其实可以直接在VIM中编辑以下就好了。

FPGA里面工作正常时候,在zebu里面继续尝试的时候还是会有问题,似乎总是提示我里面的memory会被优化掉,但是具体原因百思不得其解,知道最后我才发现是testbench里面的信号连接有问题,这个直接导致我的design的所有输出信号直接悬空,所以优化掉也在所难免,因为我的design里面只有一个串口输出和GPIO输出,GPIO的输出默认就是悬空的,只是串口输出连接了一个VIP, 这个串口的信号名称写错了(大小写错误)这就导致两个信号不一致,实际上是产生了四个信号,这样UART信号也就悬空了,所以相当于我的design实际是没有任何输出的。

修复好端口连接的问题,RAM模型的design终于可以正常工作了,不过还是要注意,uart transactor并不会自动识别波特率,这里面有个分频系数,这个系数还是要依据实际情况进行修改的。

最后我们再返回去看我们的带spi flash的design, 这个design里面,我们要将flash换成zebu中对应的HW IP,这个替换比较简单,需要说明的是zebu中spi flash只提供了网表文件,所以我们在utf中综合的时候要用一个黑盒代替flash,在布局布线的时候再将网表文件加到设计中就可以了。第一次尝试并不顺利,好在zebu还提供了相应的仿真模型,我们可以通过仿真来跑跑看看,在跑仿真的时候除了添加相应的.v文件外,我们还需要添加相应的c库文件,在zebu_ip目录中我们可以找到相应的.so文件。搞定之后跑个仿真,真的发现问题了,具体问题是spi_io2和spi_io3是三态的,而这两个引脚又有nWP和nHold两个功能,所以悬空状态是会出问题的,解决方法有两个,一个是设置成pull_up的状态,另一个是修改IP以适应这种情况,当时没有研究zebu里面怎么pull_up,就顺着design改了一下,好在运气不错,一跑就通了,换到实际zebu硬件上跑的时候也有反应了,不过不是特别问题,怀疑是reset的问题,于是就将reset逻辑换成了自己定义的一个逻辑,从效果上看是好了很多。

这里也要说明一下,zebu中我们一般是需要重新搞一个reset逻辑的,不能直接用zebu时钟上面的reset信号,经历了上述改动,最后终于可以正常跑起来了,oh yeah!

发表新评论