【问题标题】:Simulated Verilog Outputing all X's.. I've been very careful with Reg vs Wires模拟 Verilog 输出所有 X .. 我对 Reg vs Wires 非常小心
【发布时间】:2013-11-20 06:29:41
【问题描述】:

我想弄清楚为什么模拟输出都是 X 的原因。通过在整个网络上查找 verilog 问题,在我看来,大多数问题都源于 reg 与 wire 的事故,但如果觉得它可能仍然是我的困境的根源。

如果有人能告诉我在编写我的模块和模块的测试台时我做错了什么,我将不胜感激。

该模块是一个存钱罐,可以根据硬币增加其信用或根据购买的物品删除信用。我正在使用一个 8 位累加器。

测试台还远未完成,但我只是想得到“x”以外的东西,但无济于事。再次感谢您的帮助。

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

【问题讨论】:

    标签: verilog simulate


    【解决方案1】:

    您是否查看了模拟的输入以确保它们按预期进行切换?

    您的 piggyBank 模块看起来不错,但我猜您的测试台可能不会超出永远时钟语句,因为它将永远执行此行并且不会超出以下语句。因此永远不会进入季度,并且模块永远处于未重置/未修改状态。

    尝试将时钟放入单独的初始块中。

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

    此外,您似乎从未断言重置。

    最后,您似乎混淆了阻塞和非阻塞语句,尽管在您的情况下它对模拟应该不是致命的。通常你会希望你的触发器使用非阻塞赋值(

    【讨论】:

    • 我只是用一根线作为时钟,它也解决了这个问题。非常感谢您的帮助!
    【解决方案2】:

    我同意 Tim 和 DOS。正如蒂姆所说,您拆分 initial 块并发出 reset 然后 TB 在当前状态下应该可以正常工作。请参阅以下代码以供参考。这在我的地方有效。

    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
    

    【讨论】:

      【解决方案3】:

      我同意蒂姆的观点, 作为指导,我建议在描述时钟触发逻辑时使用非阻塞分配

      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
      

      在你的测试台中,对我有用的是有一个初始块来设置默认值。

      【讨论】:

        【解决方案4】:

        您的代码存在几个问题。

        首先,您的重置将无法正常工作。您需要添加一个 else 并用 begin/end 语句包围所有内容,以便当复位信号为高电平时,唯一分配给 tmp 的是初始值。此外,如果数字是十进制,您可以写 8'd0。

        其次,测试台永远不会超越时钟生成。您至少需要 2 个单独的初始语句。一个生成时钟,另一个生成实际的测试台信号。如果它们没有分开,它们就不能并行运行,你可以有一个时钟,或者你可以运行测试台,但不能同时运行。

        第三,复位信号永远不会被断言。您实际上需要将复位线设置为高电平,等待一两个时钟周期,然后将其置低。否则 tmp 将永远不会被初始化,并且在 verilog 中,所有未初始化的变量都是“x”,并且对 x 的许多(全部?)操作会导致 x。

        修复所有这些后,您的代码在 iverilog 中运行良好,输出计数为 0、25、50、75、100。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-11-27
          • 1970-01-01
          • 1970-01-01
          • 2017-01-10
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多