|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
x
本帖最后由 liusheng83 于 2014-1-26 14:06 编辑
发现Candence NC-Verilog(版本号:INCISIV-10.20.045-lnx86)在模拟SV的队列时的内存泄露问题
A memory leak bug of Candence NC-Verilog (INCISIV-10.20.045-lnx86) when simulating the queue of systemverilog
【注】该问题来源于工程实践。
能够观察到的行为是整个运行过程中,NC的模拟结果是正确的,但占用的内存从几百M迅速上升至大于20G,最后NC挂掉或服务器死机。本人找了三天,最终发现是NC模拟器本身内存泄露的Bug。现将抽象的、反应这一问题的原型程序贴出来,希望后来者遇到相同问题时有所启发。
module queue(/*AUTOARG*/
//Outputs
wrt_bsy, rtn_valid, rtn_data,
//Inputs
clk, rst_n, wrt_en, wrt_data, rtn_bsy));
input clk;
input rst_n;
input wrt_en;
input[63:0] wrt_data;
input rtn_bsy;
output reg wrt_bsy;
output reg rtn_valid;
output reg[63:0] rtn_data;
reg[63:0] rtn_queue[$:127];
integer length;
assign length=rtn_queue.size();
always @ (posedge clk)
if(wrt_en) rtn_queue.push_back(wrt_data);
always @ (posedge clk or negedge rst_n)
begin
if(!rst_n) begin
rtn_valid<='b0;
rtn_data<='b0;
end
else if((length!=0) && !rtn_bsy)
begin
rtn_valid<=1'b1;
rtn_data<=rtn_queue.pop_front();
end
else begin
rtn_valid<='b0;
rtn_data<='b0;
end
end
always @ (posedge clk or negedge rst_n)
begin
if(!rst_n)
wrt_bsy<=1'b0;
else if(length<=32)
wrt_bsy<=1'b0;
else wrt_bsy<=1'b1;
end
endmodule
module test();
reg clk;
reg rst_n;
reg wrt_en;
reg rtn_bsy;
reg[63:0] rtn_data;
wire wrt_bsy;
wire rtn_valid;
wire[63:0] rtn_data;
initial begin
$shm_open("queue.shm",,,,,);
$shm_probe(queue,"AC");
end
queue queue(/*AUTOINST*/)
//Outputs
.wrt_bsy (wrt_bsy),
.rtn_valid (rtn_valid),
.rtn_data (rtn_data[63:0]),
//Intputs
.clk (clk),
.rst_n (rst_n),
.wrt_en (wrt_en),
.wrt_data (wrt_data[63:0]),
.rtn_bsy (rtn_bsy));
initial begin
clk=0;
forever #1 clk=~clk;
end
initial begin
#0.1
rst_n=1;
#2
rst_n=0;
#2
rst_n=1;
end
reg[127:0] i;
initial begin
#10
for(i=1;i<10000000;i=i+1) begin
if(!wrt_bsy) begin
wrt_en=$random%2;
wrt_data={$random,$random};
end
else begin
wrt_en='b0;
wrt_data='b0;
end
#2;
end
$stop(2);
end
initial begin
rtn_bsy=1'b1;
#0.2
forever #20 begin
rtn_bsy=1'b0;
#2
rtn_bsy=1'b1;
end
end
endmodule
NC在编译上述代码时没有报warning和error,但是模拟时占用的内存会越来越大,直至崩溃,该问题本质上是内存没有释放的问题,即memory leak问题。如果将上述代码中的assign length=rtn_queue.size()删除,并且所有使用length的地方替换为rtn_queue.size(),则上述问题消失。 |
|