0
点赞
收藏
分享

微信扫一扫

32.SoCKit ROM读取图片再通过VGA显示之仿真

青乌 2023-05-29 阅读 50


硬件平台:Altera SoCKIt(芯片型号:Cyclone V SoC 5CSXFC6D6F31)

软件平台:Quartus II,Modelsim,Matlab

1.将图片保存为mif格式

先查看FPGA自带的ROM有多大:

32.SoCKit ROM读取图片再通过VGA显示之仿真_数据

如果采用640x480@60+RGB565模式显示,,占用空间为

640*480*16/1024=4800kB<5140(此处可以用win10自带计算器)

存储空间足够。

转mif方法:

1.Quartus II自带工具

2.Matlab编程

3.用正点原子家的PicToMif_V1.0软件实现一键图片转mif

效果如下:

32.SoCKit ROM读取图片再通过VGA显示之仿真_连线_02

用记事本打开mif文件

32.SoCKit ROM读取图片再通过VGA显示之仿真_数据_03

(事实证明,还需要把mif转成hex,hex文件形式如下):

32.SoCKit ROM读取图片再通过VGA显示之仿真_连线_04

2.新建工程

用New Project Wizard新建工程,文件子目录采用正点原子的doc,par,rtl,sim,添加芯片型号Cyclone V 5CSXFC6D6F31C6,EDA仿真选Modelsim。

3.建一个空白顶层v文件

4.调用ROM IP核

用MegaWizard Plug in导入ROM IP核,选择单端口ROM,16位宽,深度256对于这个50x50的emoji够用了。(后来证明这边也设置错了)不需要在输出添加一个寄存器寄存一下,也不需要创建时钟使能信号,异步复位。读使能信号设置一下。添加一下刚才生成的mif文件。

5.调用一个PLL IP核提供时钟

手册上外部晶振(crystal ocsillator)提供的时钟是50MHz

32.SoCKit ROM读取图片再通过VGA显示之仿真_连线_05

吹爆这个芯片的PLL,还能设成小数,nice(频率参考VGA640x480@60时的推荐频率),不过生成时间略久。甚至还可以配置动态相移(后来发现这个好像要调用PLL reconfig IP核,没做过,待确认)

 

32.SoCKit ROM读取图片再通过VGA显示之仿真_IP_06

intelPLL中文文档

 6.驱动和显示模块编写

用正点原子的示例代码改了改模块名,图片参数等等。

7.编写激励文件:

在Process-Start-Start test bench template writer新建激励文件,然后打开

这个工程中,只要设置系统时钟和复位信号就好了,单位时间设成1ns。

setting-stimulation里面编译vt文件,注意名字要和vt文件模块名一致。别忘了点add

32.SoCKit ROM读取图片再通过VGA显示之仿真_数据_07

8.用正点原子示例跑Modelsim联合仿真

电脑明显地烫了起来

仿真结果是RGB输出一直是0,查看场同步信号,发现是因为扫描一行要花800个clk,而我们图片是放在屏幕中间显示的,仿真时间设成1ns,而且时钟是系统时钟(50MHz)的一半(25.175MHz)的话,仿真大概要跑0.4s才能看到显示图片的第一行。

(后来发现下面这个图是真的重要,这三四天不知道回头看了多少次)

32.SoCKit ROM读取图片再通过VGA显示之仿真_IP_08

所以改动程序,将图片放在屏幕左上方显示 

点击Tools-Netlist-RTL Viewer,查看线有没有连错

 

tools/windows preferences/grid & timeline中的time units可以改Modelsim的Wave时间单位

时钟周期是0.02ns,理论上行同步周期是(0.02x2x800)=32ns,而实际仿真测得也是约32ns。

第一次场同步有效持续时间应该是32x(480)=15360ns

32.SoCKit ROM读取图片再通过VGA显示之仿真_数据_09

仿真的结果和理论预计的一样。说明用Modelsim跑VGA的仿真是可行的,基于正点原子改编的VGA程序应该也是可以用的。

 9.测试自己改的程序

主要是自己重头新建了工程和文件,芯片选用SoCKIt的芯片。新建过程在文中前半段展示了。

行同步信号一直为低,先检查线有没有连错了。检查发现没错。

32.SoCKit ROM读取图片再通过VGA显示之仿真_连线_10

因为Modelsim的wave窗口默认只显示output的信号。为了观察内部信号,在Modelsim的sim窗口选择模块,Object窗口中选择想要观测的内部信号。在wave窗口点restart

 模块从左往右查,先查PLL

时钟有鬼,输出第一个时钟就没信号了。

回头翻Altera的datasheet

32.SoCKit ROM读取图片再通过VGA显示之仿真_数据_11

Altera 的PLL是等级数越低,速度越快

点击模块图的+号,可以把模块展开

32.SoCKit ROM读取图片再通过VGA显示之仿真_连线_12

 查看了连线以及复位信号,都没问题

问了几个技术群大佬都无果之后,胡师哥发现仿真的时间单位有点小,追问之下才发现自己把timescale设成10ps,太小了,ip核仿真会有问题。ip核仿真的是物理模型,它把所有内部时延都加上了,不能随便设频率。

用的是红箭头下的PLL。而IO下面的PLL,用10ps仿真照样ok。

把仿真时间改成1ns后,PLL好了,漂亮的二分频

32.SoCKit ROM读取图片再通过VGA显示之仿真_连线_13

排查了各种复位信号,都没有错

回头发现这个PLL跑到325ns的时候,信号又没了。果断回头一行行看Intel的ip核英文手册以及亚德诺的PLL教育视频。

PLL的学习笔记

发现切换或者新打开工程的时候,得重新手动添加激励文件,这是一个坑,不小心就会加载成别的激励文件了。

 

回想起师哥说的ip核是物理仿真,于是再激励文件的时间尺度改大,从1ns改成10ns时钟电平翻转,真真切切地做到50MHz系统时钟。果然PLL时钟不再凭空消失了。

32.SoCKit ROM读取图片再通过VGA显示之仿真_连线_14

现在不是显示默认的黑色(全0)了,而是都是绿色(即设置的无图片区域颜色),行同步信号和场同步信号均正常,说明vga模块正常。ROM读取有问题,没有加载出图片。

观看ROM的几个端口信号,发现时钟,地址,使能信号均正常,但是输出数据一直为0。程序无误,是ROMip核设置有误。

打开魔术棒,重新检视ROM窗口。发现问题如下:

1.图片转换为mif,实际上的大小是48x48。以后生成mif文档之后,还是得亲自打开看看具体大小才是。

2.ROM的字数算错了。48x48=2304,word的数也不够。

3.最要命的,ROM设成了双时钟。。。改正过来了。应该是当时手贱。并且ROM在RTL框图是没有的,所以在看连线是否正确的时候没有排查到。

32.SoCKit ROM读取图片再通过VGA显示之仿真_连线_15

要点开RTL的+号才能看到ROM

32.SoCKit ROM读取图片再通过VGA显示之仿真_连线_16

改完后,先进行理论分析。

坑:Modelsim的Wave窗口,如果点decimal显示十进制数的话,它默认第一位是负数的,因此一个正数一直累加,会发现它变负了。应该点Unsigned完成十六进制向十进制的转化。

wave窗口底下有个滚动条,可以方便在时间轴上快速前进和后退。

第一个像素显示的时间,应该是场同步信号第一次到有效数据,并且行同步信号也到达有效数据

时刻为(20x2)x800x(2+33)+(96+48)x20x2=1,125,760ns。考虑到PLL稳定花费的时间,因此实际的时间应该会再往后十几,几十ps这样。(不过这个尺度可以几乎忽略不计了)

然后这行每显示一个像素所需时间是20x2x800=32,000ns。

行同步和场同步仿真时序均正确。注意它们都是从零开始累加的。

32.SoCKit ROM读取图片再通过VGA显示之仿真_数据_17

问题很明显了,就是ROM数据读不出来。(事实证明,因为所有输入信号都正常,原因是ROM数据为空)

ROM就这四个端口:

32.SoCKit ROM读取图片再通过VGA显示之仿真_连线_18

重新回去,发现是ROM空间给太小了。调整了ROM空间之后,依旧读不出来。

忽然想到是不是Modelsim的问题。

百度了之后发,编译后在Modelsim运行时会出现ver文件,供Modelsim识别。

打开文件夹后发现mif文件已经在编译时自动从桌面拷贝了一份到simulation文件夹下,但是ver文件就是不生成。

于是打算手动生成ver文件,但是mif不能直接转,得用hex。

mif转hex两步走,一,将mif文件的数据转换为unsigned decimal后,复制;二,新建hex文件(注意位宽和深度),粘贴,保存(注意保存路径)。

把ROM的文件换成hex,编译失败,原因是把hex放在了simulation文件下。。。保险起见,命名改成英文而不是数字,并且把hex文件移动到桌面上再添加

下面是把hex放在simulation文件夹下时候的报错信息

报错:

Error (127001): Can't find Memory Initialization File or Hexadecimal (Intel-Format) File D:/FPGA/development/ReadPic/par/1.hex for ROM instance 
 

更正后重新编译,Modelsim跑仿真。rgb输出时序就对了!(1,1)输出背景色绿色,之后这行的第2-49个像素格输出图片颜色

32.SoCKit ROM读取图片再通过VGA显示之仿真_IP_19

hex的同级目录下出现了ver文件

32.SoCKit ROM读取图片再通过VGA显示之仿真_数据_20

都生成了,不打开来看一下吗?神奇的鸟语编码。

32.SoCKit ROM读取图片再通过VGA显示之仿真_连线_21

需要注意的是,正点原子的教程,当图片从(0,0)这个位置开始显示的时候是有逻辑错误的。具体分析就不写在这边了,主要是ROM使能信号是由像素点位置决定的,而(0,0)这个位置,导致ROM在一开始,行同步信号和场同步信号均没到达有效数据段的时候,ROM使能信号就被拉高了,然后ROM地址就开始自加。

在源代码的基础上修正这个bug需要大改结构,而从(0,0)这个位置开始写入图片,逻辑其实是比较简单的,不如到需要的时候另起炉灶。

 

总结:

1.编写代码,调用ip核等,每一步都要严格遵循官方手册。

2.核对好连线。

3.跑仿真前要先进行预期时序理论分析。

4.按照时钟,ip核,然后各模块从左到右分析。

5.要熟练掌握EDA调试功能。

6.勤用英文搜索。

 

 

 

举报

相关推荐

0 条评论