今天遇到一個有網友提問:在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值確實是有了變化。

感謝大家的閱讀。祝大家工作順利,學業有成。