IC设计: 计算ring buffer的空闲条目
扫描二维码
随时随地手机看文章
在IC设计中,我们经常需要计算buffer ring的空闲条目。常见的应用有同步FIFO、异步FIFO、确认序列滑窗、outstanding序列判断。
在本案例中,wr_ptr表示下一个写指针,初始值为0,每写入一个数值,则wr_ptr加1,累加到最大值后翻转到0。rd_ptr表示下一个读指针,初始值为0,每写入一个数值,则rd_ptr加1,累加到最大值后翻转到0。以ring_len表示所有的buffer ring的条目总数,空闲的条目数量。

以buffer_ring有4个条目为例(ring_len为4),wr_ptr/rd_ptr位宽为3bit,数值范围为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发生翻转的次数是一样的,wr_ptr减去rd_ptr得到有效的空闲条目。
• 如果wr_ptr小于rd_ptr,则说明wr_ptr发生翻转的次数比rd_ptr发生翻转的次数多一次,此时ring_len加wr_ptr减去rd_ptr得到有效的空闲条目。
1.1.案例
case1: wr_ptr为3’d0,rd_ptr 为3’d7, 空闲条目数量为1(8+3’d0-3’d7)。
case2: wr_ptr为3’d5,rd_ptr 为3’d3,空闲条目数量为2(3’d5-3’d3)
2.空闲条目的计算方式2
因为在本案例中ring_len为4,属于2的整数幂,且二进制整数,以补码的形式表达负数,因此可以采用更简单的计算方式,即empty_entry_num等于(wr_ptr[2:0] - rd_ptr[2:0])。如果ring_len不为2的整数幂,则此方法不可用。
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, 空闲条目数量为1。计算过程如下,3’d0减去3’d7得到-7。
-7的补码计算
原码:1111 (最高位 1 表示负数,数值部分为 111 → 7)
反码:1000 (原码取反)
补码:1001 (反码 +1)
最终补码1001去低3bit赋值给empty_entry_num。
3.如何判断ring buffer是否溢出
判断原理如下
• 如果wr_ptr大于rd_ptr且wr_ptr减去rd_ptr大于 ring_len则溢出
• 如果wr_ptr小于rd_ptr且wr_ptr加上翻转长度(即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 ; //beginif((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 ;elsering_buff_ovfl = 1'b0 ;endendfunction





