How to stop program in testbench?

104 Views Asked by At

I try to write a program to test a hamming code with one error bit. My design part have finished, but my test bench still has some problem. When I hit start the program just keep running for a long period without result and never stops. My design is

// 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)
        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


My test bench is

// 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

I don't know what's wrong with my code.

eda playground

entire execute message

[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

I have tried putting some variables that will be used to the top of my program, because I don't know the way to pass values is the same as C++ or not. I also tried add $finish; in my test bench and expect it to stop automatically, but in vain.

1

There are 1 best solutions below

2
On

I have reproduced it in a stand-alone vcs. The issue is that you introduced a series of zero-delay loops in simulation:

always @* begin
    if(hamming_code[1] == 1)
           count[5]=count[5]+1;
    ....
end

What happens here is that as soon as hamming_code[1] becomes '1', the value of count[5] will change. As soon as it changes, it will re-evaluate the always block. hamming_code[1] stays the same, so the count[5] will change again and so on.

To break a loop, you will need a clock (and a flop).

A good vcs run-time qualifier to use to detect such loops is +vcs+loopdetect+100000 or any other big number.

Also note, that count[5] in your case is a one-bit signal. Adding '1' to it does not make much sense in particular in combination with 'count[num]%2'. Same story with error_bit.