You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决汉明码检测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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 11:30:57