Синтаксическая ошибка счетчика Джонсона. Неожиданный токен: сгенерировать

#logic #verilog #system-verilog

#Логические #verilog #system-verilog

Вопрос:

Мой преподаватель в колледже попросил меня реализовать счетчик Джонсона и его тестовый стенд с шириной <=32 (он называет это параметром N), и реализация должна использовать generate/for структуры. Хотя я немного узнал о счетчике Джонсона, я не знаю, как использовать generate в этом случае, и у меня были некоторые ошибки, когда я пытался запустить тестовый стенд. Вот моя реализация на данный момент:

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

  always @ (posedge clk) begin
    if (!rstn)
      out <= 1;
    else begin
      out[N-1] <= ~out[0];
      generate
        for (int i = 0; i < N-1; i=i 1) begin
          out[i] <= out[i 1];
        end
      endgenerate

    end
  end
endmodule
 

Вот тестовый стенд:

 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
 

Любая помощь приветствуется =)

Ответ №1:

Использование таким образом незаконно generate .

Для вашего кода требуется только for цикл (без generate ):

   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
 

Для generate синтаксиса обратитесь к стандарту IEEE Std 1800-2017, раздел 27. Генерировать конструкции.

Ответ №2:

Я попытался реализовать его с помощью generate конструкции. Я тоже новичок в этом, поэтому, если кто-нибудь увидит какую-либо проблему или ошибку или может предложить какие-либо предложения по повышению производительности, я был бы признателен.

Что касается вашего вопроса, я всегда использую generate для создания нескольких модулей, я думаю, это делает мой код более чистым и понятным. Итак, что я сделал, так это определил простой общий триггерный модуль, который я буду использовать для его создания. Если вы хотите использовать generate , вы должны определить итеративную переменную с genvar помощью . Кроме того, вы должны использовать generate вне блока always (я не знаю, есть ли ситуация, когда вы могли бы использовать его внутри блока 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
 

Здесь у вас тоже есть тестовый стенд. Одна вещь, которую я изменил в вашем коде, — это dumpfile строка. Он должен идти раньше dumpvar .

 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
 

Этот код был протестирован с использованием EDA Playground, и он работал нормально, но, как я уже сказал, я не эксперт, поэтому, если кто-нибудь обнаружит какую-либо ошибку или у вас есть какие-либо предложения, это приветствуется.