【问题标题】:Asynchronous reset D flipflop code syntax error异步复位 D 触发器代码语法错误
【发布时间】:2016-10-15 05:36:52
【问题描述】:

我正在编写代码来实现异步重置 D Flipfip,但 always@ 行显示语法错误:

`timescale 1ns / 1ps



module Dflipflop(
input D,
input reset,
input clk,
output Q

);
reg Q;

initial
begin    
    if(reset==1)    //clear the output (Q=0)
    begin
        Q <= 0;
    end
    else if(reset==0)
    begin
        always@(posedge clk) //syntax error here...
        begin
            Q <= D;
        end
    end
end

endmodule

可能的错误是什么,是否有更好的逻辑来实现相同的错误?

【问题讨论】:

    标签: verilog hdl


    【解决方案1】:

    首先,我不鼓励您使用initial 语句,除非在测试台中。这是不可合成的,因此不应出现在 RTL 中。

    那么我认为您将 Verilog 与标准编程语言混淆了。

    在 Verilog 中,有两类语句:

    • 进程,例如alwaysinitial
    • 赋值,assign 允许您直接将“值”分配给线路

    在进程中可以区分两个类:

    • 同步进程,//do something 语句 begin end 将仅在出现 @ 中指定的边时进行评估

      always @ (posedge clock) begin
        //do something
      end
      
    • 组合过程,//do something 语句将在每次 //do something 块中使用的 wirereg 的值更改时进行评估

      always @* begin
        //do something
      end
      

    在这里,您在一个没有物理现实的过程中实例化了一个过程。

    还有一点,如你所描述的你想激活进程只有当reset==0所以你放了一个条件进入进程。再一次,这在综合方面没有任何意义。该过程应该被激活,也就是在这个过程中应该评估条件。

    使用异步复位实现 D 触发器的经典解决方案如下:

    module Dflipflop(
      input D,
      input reset,
      input clk,
      output reg Q
    );
    always @ (posedge clk or negedge reset) begin
      if (!reset)
       Q <= 1'b0; // Clear Q when reset negative edge occurs
      else
        Q <= D;    // Capture D in Q when clk positive edge occurs and reset is high
    end
    endmodule
    

    【讨论】:

      【解决方案2】:

      你不能总是在初始状态下阻塞。应该这样写:

      `timescale 1ns / 1ps
      
      
      module Dflipflop(
      input D,
      input reset,
      input clk,
      output Q
      );
      reg Q;
      
      always @(posedge clk, posedge reset)
      begin    
          if(reset==1)    //clear the output (Q=0)
          begin
              Q <= 0;
          end
          else 
          begin
              Q <= D;
          end
      end
      
      endmodule
      

      【讨论】:

        【解决方案3】:

        您应该使用初始(不推荐用于综合)或始终使用。一个程序块不能进入另一个程序块。如果你真的对设计一个不可综合的逻辑感兴趣并且想尝试使用初始,你可以做下面提到的这样的事情。 initial 和 always 都是程序块。

          ....
        
            else if(reset==0)
                begin
                    repeat(100000) @(posedge clk) 
                    begin
                        Q <= D;
                    end
                end
            end
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-09-22
          • 2018-07-26
          • 2015-08-09
          相关资源
          最近更新 更多