Logic 约翰逊计数器语法错误。意外令牌:生成

Logic 约翰逊计数器语法错误。意外令牌:生成,logic,verilog,system-verilog,Logic,Verilog,System Verilog,我的大学老师要求我实现一个约翰逊计数器及其测试台,宽度以这种方式使用generate是非法的 对于您的代码,只需要一个For循环(不需要generate): 始终@(posedge clk)开始 如果(!rstn) out我尝试使用generate构造实现它。我在这方面也是新手,所以如果有人发现任何问题或错误,或者可以提供任何改进性能的建议,我将不胜感激 关于你的问题,我总是使用generate来实例化几个模块,我认为这会使我的代码更清晰,更容易理解。所以我所做的就是定义一个简单的D触发器模块,

我的大学老师要求我实现一个约翰逊计数器及其测试台,宽度以这种方式使用
generate
是非法的

对于您的代码,只需要一个
For
循环(不需要
generate
):

始终@(posedge clk)开始
如果(!rstn)

out我尝试使用
generate
构造实现它。我在这方面也是新手,所以如果有人发现任何问题或错误,或者可以提供任何改进性能的建议,我将不胜感激

关于你的问题,我总是使用
generate
来实例化几个模块,我认为这会使我的代码更清晰,更容易理解。所以我所做的就是定义一个简单的D触发器模块,我将用它来实例化它。如果要使用
generate
,必须使用
genvar
定义一个迭代变量。另外,您应该在always块之外使用
generate
(我不知道是否存在可以在always块内部使用它的情况)。下面,您可以看到代码

module ff 
  (
    input clk,
    input rstn,
    input d,
    output reg q,
    output reg qn
  );
  
  always @(posedge clk)
    begin
      if(!rstn)
        begin
          q <= 0;
          qn <= 1;
        end
      else
        begin
          q <= d;
          qn <= ~d;
        end
    end
endmodule

module johnsonCounter #(parameter N = 4)  
  ( 
    input clk,                
    input rstn,
    output [N-1:0] out,
    output [N-1:0] nout
  );    

  genvar i;
  generate
    for (i = 0; i < N-1; i=i+1) begin
      ff flip (.clk(clk), .rstn(rstn), .d(out[i+1]), .q(out[i]), .qn(nout[i]));
    end
  endgenerate
  
  ff lastFlip (.clk(clk), .rstn(clk), .d(nout[0]), .q(out[N-1]), .qn(nout[N-1]));
endmodule
这段代码是用EDA操场测试的,它工作得很好,但正如我所说,我不是专家,所以如果有人发现任何错误或有任何建议,我们欢迎

module tb;
  parameter N = 32;
  
  reg clk;
  reg rstn;
  wire [N-1:0] out;
  
  johnsonCounter    u0 (.clk (clk),
                .rstn (rstn),
                .out (out));
  
  always #10 clk = ~clk;
  
  initial begin
    {clk, rstn} <= 0;

    $monitor ("T=%0t out=%b", $time, out);
    repeat (2) @(posedge clk);
    rstn <= 1;
    repeat (15) @(posedge clk);
    $finish;
  end
  
  initial begin
    $dumpvars;
    $dumpfile("dump.vcd");
  end
endmodule
ERROR VCP2000 "Syntax error. Unexpected token: generate[_GENERATE]. This is a Verilog keyword since IEEE Std 1364-2001 and cannot be used as an identifier. Use -v95 argument for compilation." "design.sv" 13  7
ERROR VCP2020 "begin...end pair(s) mismatch detected. 2 <end> tokens are missing." "design.sv" 17  7
ERROR VCP2020 "module/macromodule...endmodule pair(s) mismatch detected. 1 <endmodule> tokens are missing." "design.sv" 17  7
ERROR VCP2000 "Syntax error. Unexpected token: endgenerate[_ENDGENERATE]. This is a Verilog keyword since IEEE Std 1364-2001 and cannot be used as an identifier. Use -v95 argument for compilation." "design.sv" 17  7
  always @ (posedge clk) begin
    if (!rstn)
      out <= 1;
    else begin
      out[N-1] <= ~out[0];
      for (int i = 0; i < N-1; i=i+1) begin
          out[i] <= out[i+1];
      end
    end
  end
module ff 
  (
    input clk,
    input rstn,
    input d,
    output reg q,
    output reg qn
  );
  
  always @(posedge clk)
    begin
      if(!rstn)
        begin
          q <= 0;
          qn <= 1;
        end
      else
        begin
          q <= d;
          qn <= ~d;
        end
    end
endmodule

module johnsonCounter #(parameter N = 4)  
  ( 
    input clk,                
    input rstn,
    output [N-1:0] out,
    output [N-1:0] nout
  );    

  genvar i;
  generate
    for (i = 0; i < N-1; i=i+1) begin
      ff flip (.clk(clk), .rstn(rstn), .d(out[i+1]), .q(out[i]), .qn(nout[i]));
    end
  endgenerate
  
  ff lastFlip (.clk(clk), .rstn(clk), .d(nout[0]), .q(out[N-1]), .qn(nout[N-1]));
endmodule
module tb;
  parameter N = 4;
  
  reg clk;
  reg rstn;
  wire [N-1:0] out;
  
  johnsonCounter    u0 (.clk (clk),
                .rstn (rstn),
                .out (out));
  
  always #10 clk = ~clk;
  
  initial begin
    {clk, rstn} <= 0;

    $monitor ("T=%0t out=%b", $time, out);
    repeat (2) @(posedge clk);
    rstn <= 1;
    repeat (15) @(posedge clk);
    $finish;
  end
  
  initial begin
    $dumpfile("dump.vcd");
    $dumpvars;
  end
endmodule