Simulated Verilog Outputing all X's.. I've been very careful with Reg vs Wires

StackOverflow https://stackoverflow.com/questions/20088978

  •  02-08-2022
  •  | 
  •  

質問

I'm reaching my wits end trying to figure out why the simulated output is all X's. From looking up verilog issues all over the web it appears to me that most issues stem from reg vs wire mishaps however if feel it may still be the root of my woes.

If anyone could please tell what I'm doing wrong writing my module and the module's test bench it would be VERY appreciated.

The module is of piggy bank that increments it's credits in terms of coins or removes credits in terms of items purchased. I'm using an 8 bit accumulator.

The test bench is far from complete but I was just trying to get something besides "x"'s to no avail. Thanks again for you help.

module piggyBank(clk, reset, penny, nickel, dime, quarter, apple, banana, carrot, date,         credit);
  input clk, reset, penny, nickel, dime, quarter;
  input apple, banana, carrot, date;
  output [7:0] credit;
  reg [7:0] tmp;

 always @(posedge clk or posedge reset)
 begin
   if (reset) 
     tmp = 8'b00000000; 
   if (penny || nickel || dime || quarter) 
     tmp = tmp + penny + (5 * nickel) + (10 * dime) + (25 * quarter); 
   if (apple || banana || carrot || date) 
     tmp = tmp - (apple * 75) - (20 * banana) - (30 * carrot) - (40 * date); 
 end

 assign credit = tmp;

endmodule

module testPiggyB();
  reg clk;
  reg reset, penny, nickel, dime, quarter;
  reg apple, banana, carrot, date;
  wire [7:0] credit;

  initial begin
   clk <= 0;
   forever #5 clk <= ~clk;
   reset <= 0;
   penny <= 0; nickel <= 0; dime <= 0; quarter <= 0;
   apple <= 0; banana <= 0; carrot <= 0; date <= 0;


   #5quarter <= 1;
   #40 quarter <= 0;
end
piggyBank pb(.clk(clk), .reset(reset), .penny(penny) ,.nickel(nickel), .dime(dime),  .quarter(quarter), .apple(apple), .banana(banana), .carrot(carrot), .date(date), .credit(credit));

endmodule
役に立ちましたか?

解決

Have you looked at the inputs to your simulation to make sure they are being toggled as you expect?

Your piggyBank module seems ok, but I guess that your testbench may not be advancing beyond the forever clock statement, as it will keep executing this line forever and not advance beyond to the below statements. Therefore the quarter is never entered, and the module stays in it's unreset/unmodified state forever.

Try putting the clock into a separate initial block.

initial begin 
  clk = 0; 
  forever #5 clk = ~clk;
end

Also you never seem to assert the reset.

Finally, you seem to be mixing up the blocking and nonblocking statements, though it shouldn't be fatal to the simulation in your case. Generally you would want your flip-flop to be using nonblocking assignments (<=), and your testbench sequential code to use blocking assignments (=).

他のヒント

I agree with Tim and DOS. As Tim has said id you split the initial block and issue a reset then the TB should work fine at the current state. See the below code for reference. This works at my place.

module piggyBank(clk, reset, penny, nickel, dime, quarter, apple, banana, carrot, date,         credit);
  input clk, reset, penny, nickel, dime, quarter;
  input apple, banana, carrot, date;
  output [7:0] credit;
  reg [7:0] tmp;

 always @(posedge clk or posedge reset)
 begin
   if (reset) 
     tmp <= 8'b00000000; 
   if (penny || nickel || dime || quarter) 
     tmp <= tmp + penny + (5 * nickel) + (10 * dime) + (25 * quarter); 
   if (apple || banana || carrot || date) 
     tmp <= tmp - (apple * 75) - (20 * banana) - (30 * carrot) - (40 * date); 
 end

 assign credit = tmp;

endmodule

module testPiggyB();
  reg clk;
  reg reset, penny, nickel, dime, quarter;
  reg apple, banana, carrot, date;
  wire [7:0] credit;

  initial begin              // Put the clock generation in a separate block.
    clk <= 0;               // Otherwise it will block your rest of the code.
    forever #5 clk <= ~clk; 
  end
  initial begin
    reset     <= 0;   // Issue a reset and then 
    #2  reset <= 1;  //  pull it down. this initializes temp.
    #10 reset <= 0; 
    penny <= 0; nickel <= 0; dime <= 0; quarter <= 0;
    apple <= 0; banana <= 0; carrot <= 0; date <= 0;
    #5  quarter <= 1;
    #40 quarter <= 0;
    #100 $finish;
  end

piggyBank pb(.clk(clk), .reset(reset), .penny(penny) ,.nickel(nickel), .dime(dime),  .quarter(quarter), .apple(apple), .banana(banana), .carrot(carrot), .date(date), .credit(credit));

endmodule

I agree with Tim, as a guideline I recommend that when you describe clock triggered logic use non blocking assignment

always @(posedge clk or posedge reset)
 begin
   if (reset) 
     tmp <= 8'b00000000; 
   if (penny || nickel || dime || quarter) 
     tmp <= tmp + penny + (5 * nickel) + (10 * dime) + (25 * quarter); 
   if (apple || banana || carrot || date) 
     tmp <= tmp - (apple * 75) - (20 * banana) - (30 * carrot) - (40 * date); 
 end

Also in your Testbench what works for me is to have an initial block to set default values.

There are several problems with your code.

First, the reset that you have will not work correctly. You need to add an else and surround everything with begin/end statements so that when the reset signal is high, the only thing that gets assigned to tmp is the inital value. Also, you can write 8'd0 if the number is in decimal.

Second, the testbench never progresses beyond clock generation. You need at least 2 separate initial statements. One generates the clock, the other generates the actual testbench signals. If they aren't separated, they can't run in parallel and you can have a clock OR you can run the testbench, but not both.

Third, the reset signal is never asserted. You need to actually set the reset line high, wait a clock cycle or two, and deassert it. Otherwise tmp will never be initialized, and in verilog all uninitialized variables are 'x' and many (all?) operations on x result in x.

After fixing all of this, your code runs fine in iverilog and the output counts 0, 25, 50, 75, 100.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top