IC設(shè)計: 計算ring buffer的空閑條目
掃描二維碼
隨時隨地手機(jī)看文章
在IC設(shè)計中,我們經(jīng)常需要計算buffer ring的空閑條目。常見的應(yīng)用有同步FIFO、異步FIFO、確認(rèn)序列滑窗、outstanding序列判斷。
在本案例中,wr_ptr表示下一個寫指針,初始值為0,每寫入一個數(shù)值,則wr_ptr加1,累加到最大值后翻轉(zhuǎn)到0。rd_ptr表示下一個讀指針,初始值為0,每寫入一個數(shù)值,則rd_ptr加1,累加到最大值后翻轉(zhuǎn)到0。以ring_len表示所有的buffer ring的條目總數(shù),空閑的條目數(shù)量。

以buffer_ring有4個條目為例(ring_len為4),wr_ptr/rd_ptr位寬為3bit,數(shù)值范圍為0~7。
1.空閑條目的計算方式1
wire?[2:0] wr_ptr;wire?[2:0] rd_ptr;wire?[2:0] empty_entry_num;assign?empty_entry_num=(wr_ptr[2:0] < rd_ptr[2:0]) ? ((1’b1<<3)+wr_ptr[2:0] - rd_ptr[2:0] ):(wr_ptr[2:0] - rd_ptr[2:0] );
??如果wr_ptr大于rd_ptr,則說明wr_ptr和rd_ptr發(fā)生翻轉(zhuǎn)的次數(shù)是一樣的,wr_ptr減去rd_ptr得到有效的空閑條目。
??如果wr_ptr小于rd_ptr,則說明wr_ptr發(fā)生翻轉(zhuǎn)的次數(shù)比rd_ptr發(fā)生翻轉(zhuǎn)的次數(shù)多一次,此時ring_len加wr_ptr減去rd_ptr得到有效的空閑條目。
1.1.案例
case1: wr_ptr為3’d0,rd_ptr 為3’d7, 空閑條目數(shù)量為1(8+3’d0-3’d7)。
case2: wr_ptr為3’d5,rd_ptr 為3’d3,空閑條目數(shù)量為2(3’d5-3’d3)
2.空閑條目的計算方式2
因為在本案例中ring_len為4,屬于2的整數(shù)冪,且二進(jìn)制整數(shù),以補(bǔ)碼的形式表達(dá)負(fù)數(shù),因此可以采用更簡單的計算方式,即empty_entry_num等于(wr_ptr[2:0] - rd_ptr[2:0])。如果ring_len不為2的整數(shù)冪,則此方法不可用。
wire?[2:0] wr_ptr;wire?[2:0] rd_ptr;wire?[2:0] empty_entry_num;assign?empty_entry_num=(wr_ptr[2:0] - rd_ptr[2:0]);
2.1.案例
case1: wr_ptr為3’d0,rd_ptr 為3’d7, 空閑條目數(shù)量為1。計算過程如下,3’d0減去3’d7得到-7。
-7的補(bǔ)碼計算
原碼:1111 (最高位 1 表示負(fù)數(shù),數(shù)值部分為?111 →?7)
反碼:1000?(原碼取反)
補(bǔ)碼:1001?(反碼 +1)
最終補(bǔ)碼1001去低3bit賦值給empty_entry_num。
3.如何判斷ring buffer是否溢出
判斷原理如下
??如果wr_ptr大于rd_ptr且wr_ptr減去rd_ptr大于 ring_len則溢出
??如果wr_ptr小于rd_ptr且wr_ptr加上翻轉(zhuǎn)長度(即1'b1<<(`PTR_WDTH))減去rd_ptr大于 ring_len則溢出
function?automatic?ring_buff_ovfl? ? ?;? ? input ? ? ? ? ? ? ? [`PTR_WDTH-1:0] ? ? rd_ptr ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?; ??//? ? input ? ? ? ? ? ? ? [`PTR_WDTH-1:0] ? ? wr_ptr ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?; ??//? ? input ? ? ? ? ? ? ? [`PTR_WDTH:0] ? ? ? ring_len ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?; ??//? ? begin? ? ? ??if((rd_ptr>wr_ptr)&&(( ({1'b0,wr_ptr}+(1'b1<<(`PTR_WDTH))) - {1'b0,rd_ptr}) >ring_len))? ? ? ? ring_buff_ovfl ? ? ? ? ? ? ? ? ? ? ? ? = ? ? ? ? ? ? ? 1'b1 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?; ??? ? ? ??else?if( (wr_ptr>rd_ptr) && ((wr_ptr-rd_ptr) > ring_len) )? ? ? ? ring_buff_ovfl ? ? ? ? ? ? ? ? ? ? ? ? = ? ? ? ? ? ? ??1'b1 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?; ??? ? ? ? else? ? ? ? ring_buff_ovfl ? ? ? ? ? ? ? ? ? ? ? ? = ? ? ? ? ? ? ? 1'b0 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?; ??? ? endendfunction





