综合器如何处理RTL中的OOB

2,123 字8 分钟

综合器如何处理RTL中的OOB

Error or Warning?探究综合器如何处理OOB

OOB是什么

OOB即Out of Boundary,Spyglass中对应的lint报错是ImproperRangeIndex

Index 'RTL_EXPRESSION' of width 'NewExprSize' is Reason_Name than the width 'ExprSize' required for the max value 'MaxValue' of the signal 'NodeName'

举个例子:

module test_index(
    // Input
    input   wire                    clk     ,
    input   wire                    rst_n   ,
    input   wire    [31:0]          i0      ,
    input   wire    [31:0]          i1      ,
    input   wire    [31:0]          i2      ,
    input   wire    [31:0]          i3      ,
    input   wire    [ 1:0]          index   ,
    input   wire    [ 1:0]          offset  ,

    // Output
    output  reg     [31:0]          o0      ,
    output  reg     [31:0]          o1      ,
    output  reg     [31:0]          o2      ,
    output  reg     [31:0]          o3
);

reg     [31:0]  array   [0:3]   ;
reg     [31:0]  t       [0:3]   ;

always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        array[0] <= 32'b0;
        array[1] <= 32'b0;
        array[2] <= 32'b0;
        array[3] <= 32'b0;
    end else begin
        array[0] <= i0;
        array[1] <= i1;
        array[2] <= i2;
        array[3] <= i3;
    end
end

always @(*)begin
    if(offset == 2'b00)begin
        t[0] = array[index+0];
        t[1] = array[index+1];
        t[2] = array[index+2];
        t[3] = array[index+3];
    end else if(offset == 2'b01)begin
        t[0] = 32'b0;
        t[1] = array[index+0];
        t[2] = array[index+1];
        t[3] = array[index+2];
    end else if(offset == 2'b10)begin
        t[0] = 32'b0;
        t[1] = 32'b0;
        t[2] = array[index+0];
        t[3] = array[index+1];
    end else begin
        t[0] = 32'b0;
        t[1] = 32'b0;
        t[2] = 32'b0;
        t[3] = array[index+0];
    end
end

always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        o0 <= 32'b0;
        o1 <= 32'b0;
        o2 <= 32'b0;
        o3 <= 32'b0;
    end else begin
        o0 <= t[0];
        o1 <= t[1];
        o2 <= t[2];
        o3 <= t[3];
    end
end
endmodule

在这段代码中,index本身是2-bit,本身的值可以是0,1,2,3,那么index+0的范围是0,1,2,3,index+1的范围是1,2,3,4,index+2的范围是2,3,4,5,index+3的范围是3,4,5,6。array本身是一个包含4个32-bit一位数组的二维数组,可选范围只有0,1,2,3,明显除index+0外,index+1,2,3均可能出现不存在的选项,比如array[4], array[5], array[6],这就是OOB

OOB在仿真中的行为是什么

很简单,遇到不存在的选项,仿真中表现为X态

OOB在综合中会被推理成什么结构

下文分析

为什么要检查OOB

在一个组合逻辑块中,不完整的赋值或条件判断容易产生latch,Bed担心在index超出范围后赋值语句失效,产生Latch

OOB在综合时如何处理

为了确认该语句不会再综合时推理出latch结构,Bed让AI读综合后的网表,对标准单元进行功能化建模,还原了netlist的功能,以o3为例:

offset index o3
0 0 array[3]
0 1 array[3]
0 2 array[3]
0 3 array[3]
1 0 array[2]
1 1 array[3]
1 2 array[2]
1 3 array[3]
2 0 array[1]
2 1 array[2]
2 2 array[3]
2 3 array[2] | array[3]
3 0 array[0]
3 1 array[1]
3 2 array[2]
3 3 array[3]
可以看出来,在o3=array[idx]这个逻辑中,一旦idx > 3,工具检测不到有效约束它的值,选择按照最小面积/最合理timing去分配此处的结构,不是清零/回绕/饱和中的任何一种语义,更不会生成latch,因为它的赋值时完整的

可以类比卡诺图,有些格子指定了是0还是1,有些格子是0是1都可以,不care,在计算最小项的时候只用处理指定了0/1的格子,综合工具也只确保明确的赋值逻辑正确

总结

Bed在看Lint报告时遇到了这个问题,于是自行探索了一番,觉得这一条可以waive

只要保证输入时符合预期的,得到的输出结果也一定是符合预期的,且电路中不会产生latch

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!

打赏
综合器如何处理RTL中的OOBhttps://bedic.tech/wiki/综合器如何处理rtl中的oob
作者
Bed
发布于
2026-10-26
许可协议
保留所有权利

随机文章

评论区

分享你的想法,与大家交流讨论

正在加载评论…