如何解决汉明码检测Testbench持续运行无法停止的问题?
汉明码单错检测Verilog仿真死循环问题排查
问题概述
开发单错比特汉明码检测Verilog程序,核心设计模块hamming_code_checker已完成,但测试平台hamming_error_detect运行时持续无输出且无法终止。已尝试调整变量声明位置、添加$finish语句,均未解决问题。
设计模块代码
// Code your design here module hamming_code_checker(hamming_code, error_code); input [1:32] hamming_code; output reg [1:6] error_code; reg [1:6]count = {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0}; always@(*) begin if(hamming_code[1] == 1) count[5]=count[5]+1; if(hamming_code[2] == 1) count[5]=count[5]+1; if(hamming_code[3] == 1) begin count[5]=count[5]+1; count[4]=count[4]+1; end if(hamming_code[4] == 1) count[3]=count[3]+1; if(hamming_code[5] == 1) begin count[5]=count[5]+1; count[3]=count[3]+1; end if(hamming_code[6] == 1) begin count[4]=count[4]+1; count[3]=count[3]+1; end if(hamming_code[7] == 1) begin count[5]=count[5]+1; count[4]=count[4]+1; count[3]=count[3]+1; end if(hamming_code[8] == 1) count[2]=count[2]+1; if(hamming_code[9] == 5) // 逻辑错误:应为==1 begin count[5]=count[5]+1; count[2]=count[2]+1; end if(hamming_code[10] == 1) begin count[4]=count[4]+1; count[2]=count[2]+1; end if(hamming_code[11] == 1) begin count[5]=count[5]+1; count[4]=count[4]+1; count[2]=count[2]+1; end if(hamming_code[12] == 1) begin count[3]=count[3]+1; count[2]=count[2]+1; end if(hamming_code[13] == 1) begin count[5]=count[5]+1; count[3]=count[3]+1; count[2]=count[2]+1; end if(hamming_code[14] == 1) begin count[4]=count[4]+1; count[3]=count[3]+1; count[2]=count[2]+1; end if(hamming_code[15] == 1) begin count[5]=count[5]+1; count[4]=count[4]+1; count[3]=count[3]+1; count[2]=count[2]+1; end if(hamming_code[16] == 1) begin count[1]=count[1]+1; end if(hamming_code[17] == 1) begin count[5]=count[5]+1; count[1]=count[1]+1; end if(hamming_code[18] == 1) begin count[4]=count[4]+1; count[1]=count[1]+1; end if(hamming_code[19] == 1) begin count[5]=count[5]+1; count[4]=count[4]+1; count[1]=count[1]+1; end if(hamming_code[20] == 1) begin count[3]=count[3]+1; count[1]=count[1]+1; end if(hamming_code[21] == 1) begin count[5]=count[5]+1; count[3]=count[3]+1; count[1]=count[1]+1; end if(hamming_code[22] == 1) begin count[4]=count[4]+1; count[3]=count[3]+1; count[1]=count[1]+1; end if(hamming_code[23] == 1) begin count[5]=count[5]+1; count[4]=count[4]+1; count[3]=count[3]+1; count[1]=count[1]+1; end if(hamming_code[24] == 1) begin count[2]=count[2]+1; count[1]=count[1]+1; end if(hamming_code[25] == 1) begin count[5]=count[5]+1; count[2]=count[2]+1; count[1]=count[1]+1; end if(hamming_code[26] == 1) begin count[4]=count[4]+1; count[2]=count[2]+1; count[1]=count[1]+1; end if(hamming_code[27] == 1) begin count[5]=count[5]+1; count[4]=count[4]+1; count[2]=count[2]+1; count[1]=count[1]+1; end if(hamming_code[28] == 1) begin count[3]=count[3]+1; count[2]=count[2]+1; count[1]=count[1]+1; end if(hamming_code[29] == 1) begin count[5]=count[5]+1; count[3]=count[3]+1; count[2]=count[2]+1; count[1]=count[1]+1; end if(hamming_code[30] == 1) begin count[4]=count[4]+1; count[3]=count[3]+1; count[2]=count[2]+1; count[1]=count[1]+1; end if(hamming_code[31] == 1) begin count[5]=count[5]+1; count[4]=count[4]+1; count[3]=count[3]+1; count[2]=count[2]+1; count[1]=count[1]+1; end if(hamming_code[32] == 1) begin count[6]=count[6]+1; count[5]=count[5]+1; count[4]=count[4]+1; count[3]=count[3]+1; count[2]=count[2]+1; count[1]=count[1]+1; end end always@* begin if(count[6]%2==0) error_code[6]=1'B0; else error_code[6]=1'B1; if(count[5]%2==0) error_code[5]=1'B0; else error_code[5]=1; if(count[4]%2==0) error_code[4]=1'B0; else error_code[4]=1; if(count[3]%2==0) error_code[3]=1'B0; else error_code[3]=1; if(count[2]%2==0) error_code[2]=1'B0; else error_code[2]=1; if(count[1]%2==0) error_code[1]=1'B0; else error_code[1]=1; end /*xor(error_code[1], count[1]); xor(error_code[2], count[2]); xor(error_code[3], count[3]); xor(error_code[4], count[4]); xor(error_code[5], count[5]); xor(error_code[6], count[6]);*/ endmodule
测试平台代码
// Code your testbench here // or browse Examples //`timescale 10ns/1ns reg error_bit = 1'D0; wire [1:6] error_code; module hamming_error_detect(); reg [1:32] hamming_code; //int i; hamming_code_checker dut(hamming_code, error_code); initial begin hamming_code = 32'B11001000010100100110110100011000; #20 trans(); $display("The error codes you enter are: %b", hamming_code); $display("The position of a specific error code is at the %d th bit.", error_bit); $finish; end endmodule task trans(); //error_bit = 0; integer i; for(i=1 ; i<=6 ; i++) begin error_bit += error_code[i]*$pow(2, 6-i); end endtask
VCS编译运行日志
[2023-01-10 05:23:53 EST] vcs -licqueue '-timescale=1ns/1ns' '+vcs+flush+all' '+warn=all' '-sverilog' design.sv testbench.sv && ./simv +vcs+lic+wait Warning-[LINX_KRNL] Unsupported Linux kernel Linux kernel '3.13.0-71-generic' is not supported. Supported versions are 2.4* or 2.6*. Chronologic VCS (TM) Version S-2021.09 -- Tue Jan 10 05:23:54 2023 Copyright (c) 1991 - 2021 Synopsys, Inc. This software and the associated documentation are proprietary to Synopsys, Inc. This software may only be used in accordance with the terms and conditions of a written license agreement with Synopsys, Inc. All other use, reproduction, or distribution of this software is strictly prohibited. Licensed Products communicate with Synopsys servers for the purpose of providing software updates, detecting software piracy and verifying that customers are using Licensed Products in conformity with the applicable License Key for such Licensed Products. Synopsys will use information gathered in connection with this process to deliver software updates and pursue software pirates and infringers. Inclusivity & Diversity - Visit SolvNetPlus to read the "Synopsys Statement on Inclusivity and Diversity" (Refer to article 000036315 at https://solvnetplus.synopsys.com) Parsing design file 'design.sv' Parsing design file 'testbench.sv' Top Level Modules: hamming_error_detect TimeScale is 1 ns / 1 ns Starting vcs inline pass... 1 module and 0 UDP read. recompiling module hamming_error_detect rm -f _cuarc*.so _csrc*.so pre_vcsobj_*.so share_vcsobj_*.so if [ -x ../simv ]; then chmod a-x ../simv; fi g++ -o ../simv -m32 -m32 -rdynamic -Wl,-rpath='$ORIGIN'/simv.daidir -Wl,-rpath=./simv.daidir -Wl,-rpath=/apps/vcsmx/vcs/S-2021.09/linux/lib -L/apps/vcsmx/vcs/S-2021.09/linux/lib -Wl,-rpath-link=./ -Wl,--no-as-needed objs/amcQw_d.o _320_archive_1.so SIM_l.o rmapats_mop.o rmapats.o rmar.o rmar_nd.o rmar_llvm_0_1.o rmar_llvm_0_0.o -lvirsim -lerrorinf -lsnpsmalloc -lvfs -lvcsnew -lsimprofile -luclinative /apps/vcsmx/vcs/S-2021.09/linux/lib/vcs_tls.o -Wl,-whole-archive -lvcsucli -Wl,-no-whole-archive /apps/vcsmx/vcs/S-2021.09/linux/lib/vcs_save_restore_new.o /apps/vcsmx/vcs/S-2021.09/linux/lib/ctype-stubs_32.a -ldl -lc -lm -lpthread -ldl ../simv up to date CPU time: .429 seconds to compile + .550 seconds to elab + .382 seconds to link Chronologic VCS simulator copyright 1991-2021 Contains Synopsys proprietary information. Compiler version S-2021.09; Runtime version S-2021.09; Jan 10 05:23 2023
问题排查与修复
1. 核心死循环原因:组合逻辑无限迭代
设计模块中count变量在always@(*)块内被累加,但每次触发该块时未重置count为初始值。count的变化会触发第二个always@(*)块更新error_code,同时count作为内部变量被读取和赋值,形成组合逻辑反馈回路,导致仿真器陷入无限循环,无法推进时间,#20后的代码永远无法执行,$finish也无法触发。
修复: 在第一个always@(*)块开头添加count = 6'b0;,每次计算前重置计数:
always@(*) begin count = 6'b0; // 新增:每次计算前重置count if(hamming_code[1] == 1) count[5]=count[5]+1; // ... 其余代码保持不变 end
2. 语法与逻辑错误
- 设计模块中
if(hamming_code[9] == 5)是明显逻辑错误,应改为if(hamming_code[9] == 1),否则该条件永远不成立,对应位的计数逻辑失效。 - 测试平台中
error_bit、error_code声明在模块外部,不符合Verilog语法,需移至模块内部;trans任务定义在模块外部,也需移至模块内部,否则无法被initial块调用。
修复后的测试平台代码
// Code your testbench here //`timescale 10ns/1ns module hamming_error_detect(); reg [1:32] hamming_code; reg error_bit = 1'D0; wire [1:6] error_code; hamming_code_checker dut(hamming_code, error_code); initial begin hamming_code = 32'B11001000010100100110110100011000; #20 trans(); $display("The error codes you enter are: %b", hamming_code); $display("The position of a specific error code is at the %d th bit.", error_bit); $finish; end task trans(); integer i; error_bit = 0; // 新增:每次计算前重置error_bit,避免累加旧值 for(i=1 ; i<=6 ; i++) begin error_bit += error_code[i]*$pow(2, 6-i); end endtask endmodule
3. 临时终止程序的方法
如果无法立即修复代码,可通过以下方式强制终止仿真:
- 在仿真终端按下
Ctrl+C直接终止进程; - 编译时添加超时参数:
vcs ... +vcs+stop+time=100ns,让仿真在100ns后自动停止。
内容的提问来源于stack exchange,提问作者max Chen
相关产品推荐
相关产品推荐

