最近定位了一個bug,代碼是以前的同事留下的,沒有經過太多充分的測試,且沒有仿真平臺,定位的過程是相當的痛苦,前后花了差不多一個星期。但是解決這個bug后,回頭看,其實也是一個很簡單的問題,就是請求應答(req_ack)接口處理不正確造成的……
問題現象
項目在上板測試過程中必現報文被丟棄的現象,方案不是很復雜。FPGA從CPU獲取報文索引,然后根據索引讀取CPU內存的報文(為了描述簡單,這里省去項目相關信息)。
定位過程
1、該模塊以前沒有問題,后繼模塊工作頻率降低后,給該模塊反壓了,才會出現該問題,首先是各種統計,上板測試沒有發現問題,說明邏輯內部處理報文的時候沒有丟包;
2、這里省略1萬字各種懷疑各種測試,多方位證實了邏輯內部處理報文的時候確實是沒有丟包的;
3、懷疑是不是CPU丟了索引,或者FPGA丟了索引?但是都不太好證實,因為丟棄報文的時候FPGA本身不感知,也不知道軟件下發了多少索引。
4、在和同事一起討論懷疑點,檢視代碼的時候,看到CPU告知FPGA描述符的時候,通過寫寄存器的方式來告知,FPGA處理采用的是req_ack接口。如下圖所示:其實這也不是一個標準的req_ack接口,因為請求方只給一拍的wen信號,req和ack的處理都是應答方內部的一種處理方式。
所以有一個大膽猜想,會不會是上一次req還沒有處理完,CPU又來了下一個req導致有索引丟棄,從而導致了報文丟棄了?這個現象很好監測,當wen和req同時為1時,即為錯誤,監測代碼如下所示:
always@(posedge clk_sys or posedge rst)
begin
if(rst == 1'b1) begin
error <= 1'b0;
end
else if((wen == 1'b1) && (req == 1'b1)) begin
error <= 1'b1;
end
end
增加error信號后,再次測試的過程中,果然error信號拉高了。
解決方案
首先CPU在寫寄存器的過程中,并不知道FPGA是否正確處理上一個索引,其次FPGA處理一個索引和報文的時間是未知的,和后繼模塊的性能有關。所以解決這個問題的方案就是先緩存CPU寫入的索引,然后再讀出來慢慢處理。如下圖所示:
CPU寫入索引后,先不處理,全部緩存到一個fifo中,然后再從fifo中讀出每一個索引依次處理。修改后的方案再次做穩定性測試,上述問題不再出現。
這里會有一個問題,該fifo不會溢出嗎?在這個項目中,是不會的,因為CPU連續寫入索引的最大個數是32個,所以只要fifo的深度大于32即可。那如果CPU連續寫入索引的個數沒有限制呢?上述方案也就無效了,必須和CPU之間建立一個發壓的機制,保證CPU寫入的索引不會丟失。
總結
本案例中的問題,是使用req_ack接口時,常見的一個問題,請求方和應答方要保持好握手,在上一個任務處理結束前,不可以發起下一個任務。
另外這種接口在高性能場景下,是有一定的性能損耗,盡可能采用流式接口來處理。
-
cpu
+關注
關注
68文章
10826瀏覽量
211160 -
接口
+關注
關注
33文章
8503瀏覽量
150840 -
仿真
+關注
關注
50文章
4044瀏覽量
133421 -
內存
+關注
關注
8文章
3002瀏覽量
73887 -
代碼
+關注
關注
30文章
4751瀏覽量
68357
發布評論請先 登錄
相關推薦
評論