今天遇到一个有网友提问:在qsys系统中,system id加了,下载的时候systemid这一项校验也通过了,但是system timestamp值校验不通过。请问到底是怎么回事。用户还提供了截图,如下图所示:
而且他说,如果此时,在run的时候,勾选了忽略不匹配的系统时间戳(lgnore mismatched system timestamp)选项,就能成功run,如果不勾选,就不能run,而且即使是勾选该选项后run,run的结果也异常。
用户大概率会再次怀疑NIOS II不靠谱。
先做个总结说明,这并不是NIOS II不靠谱的表现,反而恰恰相反,这是NIOS II CPU为了降低大家使用过程中犯低级错误的概率,而设置的一套强制验证机制。
这里先对这两项的物理意义做个说明,相信说完大家就都懂问题到底在哪里了。
首先来说,网友截图的这个只能证明其当前下载的sof里面的NIOS II系统,使用的system id是自己设置的ID,其他就没法证明了。
举个例子,假设用户在D盘根目录下创建了个工程,里面加入了sysid,设置的值为0x12345678,然后调试了一段时间之后。用户希望为这个系统增加功能,为了保留这个已经调试过的工程,所以用户将这个工程拷贝到了E盘工程根目录下,然后在E盘下基于这个工程进行修改,例如加入一个UART串口外设再编译。
这个时候,两个系统的sysid都是0x12345678。此时,无论用户下载D盘的还是E盘的sof到fpga芯片,在这个界面去调试的时候读到的systemid都是0x12345678,那么用户又怎么能认为这两个工程一样呢?烧写D盘工程的sof,能调试你针对E盘的工程写的uart的程序吗。所以,单就systemid校验正确这一项,并不能确定这个工程就是对的。换句话说,只要两个工程的sysid设置的相同,这一项就能通过。
而且,从设计意图来说,systemid的存在,也不是为了帮用户确定工程的唯一性,而是为了辅助NIOS II 多核CPU架构的应用。在多核CPU应用系统中,每个NIOS II CPU总线上连接一个systemid的设备,并设置这多个system id的值不一样,这样在进行软件编程时,就可以通过检查system id的值,来确定当前要调试的CPU是多核CPU中的哪一个了。
既然这一个system id的功能也无法确保FPGA逻辑和NIOS II软件程序的一一对应关系,所以NIOS采用了第二项机制来确保硬件(sof)和软件(elf)的匹配,这个就是system timestamp功能。在每个使用到了NIOS II CPU的工程目录下,都有一个sopcinfo格式的文件,该文件中,有一个timestamp的参数,如下图所示:
这个参数,每次Quartus工程编译一次,注意,是Quartus工程编译一次,而不是qsys重新生成一次,这个timestamp的值都会变化一次。即使两次编译你没有改任何quartus中任何一个字符,两次编译,这个timestamp的值都会变化一次,都是不一样的。然后,在nios ii eds中,每次你重新编译了quartus工程,都会提示你重新generate bsp,这个重新generate bsp,就会读取你这个新的sopcinfo文件,并在system.h文件中记录这个新的timestamp参数,如下图所示:
所以说,如果你的系统在校验的时候。timestamp对不上,就一定百分之一亿的确定,你下载的sof和你当前的nios ii 用的bsp对不上。
因此,大家以后在使用NIOS II CPU进行系统设计时,加上sysid是个好习惯,通过system id和system timestap两个值来帮你辅助确认你用的两套内容到底是不是绝对对应的。
补充说明下:前文的system timestamp是系统时间戳的意思,不是在qsys中配置个timer定时器来作为程序时间戳的意思。配置timer为timestamp功能,是用来测量C程序的运行时间用的。而这个system timestamp是用来确保整个工程的软硬件匹配用的。
以下再附图两张,证明下我前面说的quartus每次编译都会更改system timestamp的值的情况。以下两个工程,两次编译时间间隔不超过5秒钟,可以看到,两次的system timestamp值确实是有了变化。
感谢大家的阅读。祝大家工作顺利,学业有成。