|  | 
 
| 
本帖最后由 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(),则上述问题消失。
 | 
 |