ZYNQ AXI_DMA_UDP以太網(wǎng)傳輸(二)問題記錄
上一篇文章只是簡單的記錄一下調(diào)試成功的代碼
但調(diào)試成功這個過程很痛苦,踩了很多坑,特此記錄,留眼以后查看
問題1:DMA傳輸過程中報錯 dma error
參考博客
xilinx dma調(diào)試筆記
ZYNQ AXI DMA調(diào)試細(xì)節(jié)
在調(diào)試過程中出現(xiàn)這類問題基本上都是這一句代碼出了問題:
axi_dma_start(MAX_PKT_LEN);
再往里面跳可以看見這樣一個函數(shù),在正點(diǎn)原子提供的例程中是這樣的
status = XAxiDma_SimpleTransfer(&axidma, (u32) rx_buffer_ptr,
pkt_len, XAXIDMA_DEVICE_TO_DMA);
出現(xiàn)報錯基本上都是因?yàn)閜kt_len設(shè)置的太小,按照xilinx dma調(diào)試筆記的說法就是**“問題是設(shè)置傳輸?shù)腟2MM buffer length太小”“這里讀出0x5011表示例化DMA的時候配置的S2MM buffer length太小,導(dǎo)致DMA在接收buff滿的時候還沒有遇到last信號,就會產(chǎn)生DMAIntErr錯誤”**
最開始的時候我在ip核中設(shè)置的位寬是23位,那么我想著那我就把這個MAX_PKT_LEN(也就是pkt_len)設(shè)置為2^23-1,這么一改之后確實(shí)沒有報錯了,dma跑通了,但是我還是有些奇怪,為什么不能太小呢,具體的范圍有嗎?
后來我看到評論里的**“這里讀出0x5011表示例化DMA的時候配置的S2MM buffer length太小,導(dǎo)致DMA在接收buff滿的時候還沒有遇到last信號,就會產(chǎn)生DMAIntErr錯誤”**突然悟了,仔細(xì)看我的數(shù)據(jù)產(chǎn)生模塊代碼,產(chǎn)生2048個32bit的數(shù)據(jù)后才會產(chǎn)生一個時鐘周期的tlast信號,如果我把MAX_PKT_LEN設(shè)置的調(diào)小,這里的dma傳輸?shù)氖且粋€字節(jié),相當(dāng)于8bit,按照之前的設(shè)置MAX_PKT_LEN=2048,那肯定接收不到talst信號呀,所以肯定會報錯的,所以有一種改法是,不動正點(diǎn)原子的代碼,增加MAX_PKT_LEN,因?yàn)楫a(chǎn)生2048個32bit的數(shù)據(jù)后才會產(chǎn)生一個時鐘周期的tlast信號,所以其實(shí)是傳遞8192個字節(jié)后產(chǎn)生talst信號,于是MAX_PKT_LEN需要大于等于8192!這么一改果然對了!興奮!當(dāng)然還有一種改法,那就是【JokerのZYNQ7020】AXI_DMA_PL_PS最下面說的那樣"所有涉及MAX_PKT_LEN的地方,都要*sizeof(u32) ;" 一開始還不是很理解,這時候才恍然大悟,所以在我自己的代碼里這一部分改成了
status = XAxiDma_SimpleTransfer(&axidma, (u32) rx_buffer_ptr,
(u32)(pkt_len*sizeof(u32)), XAXIDMA_DEVICE_TO_DMA);
之后我再設(shè)置MAX_PKT_LEN只需要設(shè)置為2048就行了
問題2:DMA傳輸過程中第一次傳輸?shù)臄?shù)據(jù)總是從5開始
這個問題本來其實(shí)是打算忽略的,因?yàn)槌说谝淮蝹鬏?,之后的傳輸又都是?開始傳輸?shù)?,但是想著留在這里始終是個刺,還是研究一下吧,沒想到一研究發(fā)現(xiàn)這個問題有點(diǎn)惱火。
我最開始的數(shù)據(jù)產(chǎn)生模塊的代碼中的狀態(tài)機(jī)轉(zhuǎn)移其實(shí)是這么寫的:
always @(*) begin
case(r_current_state)
IDLE : r_next_state = ( M_AXIS_tready) ? TRAN : IDLE;
TRAN : r_next_state = (r_M_AXIS_tdata == TRANS_NUM) ? LAST : TRAN;
LAST : r_next_state = M_AXIS_tready ? IDLE : LAST;
default : r_next_state = IDLE;
endcase
end
表面上看沒什么問題,但是按照這么寫每次第一次傳輸都從5開始,我就很奇怪,于是去ila抓信號查看,我發(fā)現(xiàn)我一進(jìn)入debug,首先不急著單步調(diào)試,而是直接在ila界面強(qiáng)制觸發(fā),發(fā)現(xiàn)信號如下圖所示:
從圖中可以看出,我的代碼還沒運(yùn)行,但是FPGA內(nèi)部好像已經(jīng)滿足了我代碼里的狀態(tài)轉(zhuǎn)移條件,一開始就是個5,但是我一看M_AXIS_tready信號又是低電平,M_AXIS_tvalid信號又是高電平,這就給我整不會了,難道是在上電過程中M_AXIS_tready有高電平的時刻?然后因?yàn)檫M(jìn)入到了TRAN狀態(tài),在這個狀態(tài)下,tvaild信號為高電平,隨即tvaild和tready進(jìn)行握手,tready信號拉低,等待dma傳輸將tready拉高。
為了驗(yàn)證這個猜想,我首先注釋掉了TRAN狀態(tài)下的tvalid信號
TRAN : begin
// r_M_AXIS_tvalid <= 1'd1;
if(M_AXIS_tready)begin
r_M_AXIS_tdata <= r_M_AXIS_tdata + 32'd1;
if(r_M_AXIS_tdata == TRANS_NUM)
r_M_AXIS_tlast <= 1'd1;
else
r_M_AXIS_tlast <= 1'd0;
end
else
r_M_AXIS_tdata <= r_M_AXIS_tdata;
end
然后跑ila發(fā)現(xiàn),
數(shù)據(jù)一直在累加,M_AXIS_tready一直是1?。。?!這證明了部分猜想,可能是因?yàn)檫M(jìn)行了握手才導(dǎo)致M_AXIS_tready拉低的,但是我又改怎么避免誤觸發(fā)呢?最后是參考了博客ZYNQ通過AXI DMA實(shí)現(xiàn)PL發(fā)送連續(xù)大量數(shù)據(jù)到PS DDR
的寫法
always @(*) begin
case(r_current_state)
IDLE : r_next_state = (pos_trans_start && M_AXIS_tready) ? TRAN : IDLE;
TRAN : r_next_state = (r_M_AXIS_tdata == TRANS_NUM) ? LAST : TRAN;
LAST : r_next_state = M_AXIS_tready ? IDLE : LAST;
default : r_next_state = IDLE;
endcase
end
觸發(fā)條件增加一個上升沿,這樣子就能解決這個bug了。
問題3:網(wǎng)口調(diào)試助手連接不上指定端口
對于這個問題我是真無語。。。一開始我用正點(diǎn)原子的教程,跟著一步一步走,但是最后就是連接不上
最后查了下最下面的報錯信息才意識到可能是端口號被占用了用不了,好家伙,結(jié)果我去查怎么查看電腦被占用的端口號,結(jié)果真占用了…于是我去招了個沒被占用的端口號,一試就成了,還是不能生搬硬套。
其實(shí)還有遇到很多問題,比如:文章來源:http://www.zghlxwxcb.cn/news/detail-839661.html
- 根據(jù)csdn中的要求,axi fifo最好打開packet模式
- 提供數(shù)據(jù)的模塊必須產(chǎn)生tlast信號給axi
fifo,否則會沒有數(shù)據(jù),這也就要求提供數(shù)據(jù)的模塊外圍得包裝一個axi協(xié)議相關(guān)的架構(gòu),包括tlast,ready、valid、keep等 - 使用以太網(wǎng)傳輸前需要確定自己的電腦哪些端口可用,否則會出現(xiàn)端口被占用導(dǎo)致無法網(wǎng)口調(diào)試的情況,如何查看被占用的端口可百度。
- 正點(diǎn)原子提供的udp發(fā)數(shù)據(jù)的代碼有個bug,傳輸數(shù)據(jù)是寫死的,自己需要簡單改成變量。 另外自定義的axi數(shù)據(jù)模塊的時鐘命名會影響block design的驗(yàn)證:不能定義為i_clk(無語)
一開始遇到這些問題真的是好折磨,但后面解決完了回過頭看還是很有收獲的,bug就是讓人成長的(笑死)。文章來源地址http://www.zghlxwxcb.cn/news/detail-839661.html
到了這里,關(guān)于ZYNQ AXI_DMA_UDP以太網(wǎng)傳輸(二)問題記錄的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!