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
- 许可协议
- 保留所有权利

评论区
分享你的想法,与大家交流讨论
正在加载评论…