Verilog:为注册表赋值

Verilog:为注册表赋值,verilog,Verilog,我有一个关于Verilog的初学者问题,我希望能得到一些帮助 下面您可以看到一个简单计数器的代码,该计数器具有: 输入:单个时钟信号,连接到时钟 输入:复位信号,连接到物理按钮 输出:计数器输出 输出:led等于复位输入 奇怪的是,当复位信号为高时,计数器不会复位为零。 在电路板上,当我按下按钮时,我可以看到led开关,因此重置为真,但if指令内部计数器我不知道代码不工作的确切原因。我现在使用VHDL。 然而,我会这样写: module simple_counter (CLOCK_50, res

我有一个关于Verilog的初学者问题,我希望能得到一些帮助

下面您可以看到一个简单计数器的代码,该计数器具有:

  • 输入:单个时钟信号,连接到时钟
  • 输入:复位信号,连接到物理按钮
  • 输出:计数器输出
  • 输出:led等于复位输入
  • 奇怪的是,当复位信号为高时,计数器不会复位为零。
    在电路板上,当我按下按钮时,我可以看到led开关,因此重置为真,但if指令
    内部计数器我不知道代码不工作的确切原因。我现在使用VHDL。
    然而,我会这样写:

    module simple_counter (CLOCK_50, reset, led, counter_out);          
    
        input CLOCK_50 ;
        input reset ;
        output led;
        output [31:0] counter_out;
    
        reg [31:0] internal_counter;
    
        always @ (posedge CLOCK_50)
          begin
             if (reset)
                internal_counter <= 0;
             else
                internal_counter <= internal_counter + 1;
    
             led <= reset;
             counter_out <= internal_counter;
          end
    endmodule
    
    模块简单计数器(时钟50、复位、led、计数器输出);
    输入时钟_50;
    输入复位;
    输出led;
    输出[31:0]计数器输出;
    reg[31:0]内部_计数器;
    始终@(posedge时钟_50)
    开始
    如果(重置)
    
    内部计数器我不知道你的代码为什么不工作。我现在使用VHDL。 然而,我会这样写:

    module simple_counter (CLOCK_50, reset, led, counter_out);          
    
        input CLOCK_50 ;
        input reset ;
        output led;
        output [31:0] counter_out;
    
        reg [31:0] internal_counter;
    
        always @ (posedge CLOCK_50)
          begin
             if (reset)
                internal_counter <= 0;
             else
                internal_counter <= internal_counter + 1;
    
             led <= reset;
             counter_out <= internal_counter;
          end
    endmodule
    
    模块简单计数器(时钟50、复位、led、计数器输出);
    输入时钟_50;
    输入复位;
    输出led;
    输出[31:0]计数器输出;
    reg[31:0]内部_计数器;
    始终@(posedge时钟_50)
    开始
    如果(重置)
    
    内部计数器您的代码不起作用,因为您对
    内部计数器
    进行了两次赋值。这是允许的,但规则是最后一次分配“获胜”

    因此,让我们在重置激活时逐步查看代码:

    if (reset)   
      internal_counter <= 0; 
    
    由于这项任务比上一项任务晚/晚,因此它“获胜”。这里没有条件,因此如果…
    ,此总是替换以前的
    。因此,
    if…
    代码变得多余。它永远不会执行,合成工具将删除任何逻辑

    正如其他人所指出的:您需要一个
    else
    部分。重置重置部分中的所有变量是一种良好做法:

    always @ (posedge CLOCK_50) // on positive clock edge
    begin
       if (reset)
       begin
          internal_counter <= 0;
          led <= 1'b1; 
          counter_out  <= 0;
       end // reset section
       else
       begin // clocked section
          internal_counter <= internal_counter + 1;
          led <= 1'b0; 
          counter_out <= internal_counter; 
       end
    end // clocked section 
    
    您的
    led
    有点奇怪。复位时为高,否则为低。我想你这样做是为了调试

    计数器输出
    始终在内部计数器后面一个值。这是你想要的吗?它还需要额外的32个寄存器。我希望不用内部计数器,直接使用计数器输出:

    always @ (posedge CLOCK_50) // on positive clock edge
    begin
       if (reset)
       begin
          led <= 1'b1; 
          counter_out  <= 0;
       end // reset section
       else
       begin // clocked section
          led <= 1'b0; 
          counter_out <= counter_out + 1; 
       end
    end // clocked section 
    
    始终@(posedge CLOCK_50)//在正时钟边缘
    开始
    如果(重置)
    开始
    
    led您的代码不起作用,因为您对
    内部\u计数器进行了两次赋值。这是允许的,但规则是最后一次分配“获胜”

    因此,让我们在重置激活时逐步查看代码:

    if (reset)   
      internal_counter <= 0; 
    
    由于这项任务比上一项任务晚/晚,因此它“获胜”。这里没有条件,因此如果…
    ,此总是替换以前的
    。因此,
    if…
    代码变得多余。它永远不会执行,合成工具将删除任何逻辑

    正如其他人所指出的:您需要一个
    else
    部分。重置重置部分中的所有变量是一种良好做法:

    always @ (posedge CLOCK_50) // on positive clock edge
    begin
       if (reset)
       begin
          internal_counter <= 0;
          led <= 1'b1; 
          counter_out  <= 0;
       end // reset section
       else
       begin // clocked section
          internal_counter <= internal_counter + 1;
          led <= 1'b0; 
          counter_out <= internal_counter; 
       end
    end // clocked section 
    
    您的
    led
    有点奇怪。复位时为高,否则为低。我想你这样做是为了调试

    计数器输出
    始终在内部计数器后面一个值。这是你想要的吗?它还需要额外的32个寄存器。我希望不用内部计数器,直接使用计数器输出:

    always @ (posedge CLOCK_50) // on positive clock edge
    begin
       if (reset)
       begin
          led <= 1'b1; 
          counter_out  <= 0;
       end // reset section
       else
       begin // clocked section
          led <= 1'b0; 
          counter_out <= counter_out + 1; 
       end
    end // clocked section 
    
    始终@(posedge CLOCK_50)//在正时钟边缘
    开始
    如果(重置)
    开始
    

    led我建议使用Verilog-2001变体进行更多改进,并且您的代码不起作用,因为在重置期间,您正在分配
    内部计数器我建议使用Verilog-2001变体进行更多改进,您的代码不起作用,因为在重置过程中,您正在分配
    内部\u计数器,只需在'led'后面添加else块,哪个分配到
    内部\u计数器
    您的东西起作用了吗?您好@Ramakrishnamada,谢谢您的建议。我实现了它,并按照Seaotter211和Oldfart的建议工作。干杯嗨@TomServo,这是我早些时候应该问自己的问题:)显然这是最后一个问题。干杯只需在'led'后面添加else块,即
    内部_计数器的哪个任务运行正常吗?嗨@Ramakrishnamada,谢谢你的建议。我实现了它,并按照Seaotter211和Oldfart的建议工作。干杯嗨@TomServo,这是我早些时候应该问自己的问题:)显然这是最后一个问题。干杯非常感谢Seaotter211,您构建它的方式看起来更好!我会落实你的建议,并让你知道结果。再次干杯!太好了,成功了。我不知道“最后一次作业获胜”的规则,只是添加了一个else语句就成功了。谢谢你,海獭!非常感谢Seaotter211,您构建它的方式看起来更好!我会落实你的建议,并让你知道结果。再次干杯!太好了,成功了。我不知道“最后一次作业获胜”的规则,只是添加了一个else语句就成功了。谢谢你,海獭!同步不需要10个寄存器,2个就足够了。您的重置同步有缺陷,因为它没有初始值,这会导致问题:如何重置重置电路?有一些解决方案,但它们超出了这个问题的范围。感谢oldfart,我修改了代码,我忘记了执行reduce和operation,感谢您指出Thank you@RAMAKRISHNAMEDA,重置同步的有趣解决方案。非常感谢:)同步不需要10个寄存器,2个就足够了。您的重置同步有缺陷,因为它没有初始值,这会导致问题:如何重置重置电路?有解决方案,但它们超出了本文的范围