Verilog 异步复位D触发器代码语法错误

Verilog 异步复位D触发器代码语法错误,verilog,hdl,Verilog,Hdl,我正在编写一个代码来实现异步重置D flipfip,但始终@行显示语法错误: `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(res

我正在编写一个代码来实现异步重置D flipfip,但
始终@
行显示语法错误:

`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
`时间刻度为1ns/1ps
模块Dflipflop(
输入D,
输入复位,
输入时钟,
输出Q
);
reg Q;
最初的
开始
if(reset==1)//清除输出(Q=0)
开始

Q您不能总是在初始值内阻塞。应该这样写:

`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
`时间刻度为1ns/1ps
模块Dflipflop(
输入D,
输入复位,
输入时钟,
输出Q
);
reg Q;
始终@(posedge时钟、posedge重置)
开始
if(reset==1)//清除输出(Q=0)
开始

Q您不能总是在初始值内阻塞。应该这样写:

`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
`时间刻度为1ns/1ps
模块Dflipflop(
输入D,
输入复位,
输入时钟,
输出Q
);
reg Q;
始终@(posedge时钟、posedge重置)
开始
if(reset==1)//清除输出(Q=0)
开始

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

然后我认为你把Verilog和一种标准的编程语言搞混了,而事实并非如此

在Verilog中,有两类语句:

  • 进程,如
    始终
    初始
  • 赋值,带有
    assign
    ,允许您直接为导线赋值
在流程中,可分为两类:

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

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

    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
模块Dflipflop(
输入D,
输入复位,
输入时钟,
输出寄存器Q
);
始终@(posedge clk或negedge重置)开始
如果(!重置)

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

然后我认为你把Verilog和一种标准的编程语言搞混了,而事实并非如此

在Verilog中,有两类语句:

  • 进程,如
    始终
    初始
  • 赋值,带有
    assign
    ,允许您直接为导线赋值
在流程中,可分为两类:

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

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

    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
模块Dflipflop(
输入D,
输入复位,
输入时钟,
输出寄存器Q
);
始终@(posedge clk或negedge重置)开始
如果(!重置)

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

  ....

    else if(reset==0)
        begin
            repeat(100000) @(posedge clk) 
            begin
                Q <= D;
            end
        end
    end
。。。。
否则如果(重置==0)
开始
重复(100000)@(posedge时钟)
开始

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

  ....

    else if(reset==0)
        begin
            repeat(100000) @(posedge clk) 
            begin
                Q <= D;
            end
        end
    end
。。。。
否则如果(重置==0)
开始
重复(100000)@(posedge时钟)
开始
Q