FPGA/Verilog

[베릴로그 개인 공부] generate문

장영현 2023. 6. 26. 17:54
728x90
  • generate

베릴로그(Verilog) 문법에서 "generate"는 코드 생성과 제어를 위해 사용되는 키워드이다. generate 블록 내에서는 일반적인 선언과 실행 흐름을 따르는 것이 아니라, 코드의 반복, 조건부 실행, 계층적 구조 등을 구현하는 데 사용된다.

 

generate 블록은 일반적으로 조건에 따라 여러 인스턴스를 생성하거나, 계층적인 모듈 구조를 생성하는 데 사용.

예를 들어, if - else문을 사용해서 generate 블록 내에서 조건에 따라 다른 모듈 인스턴스를 생성할 수 있다.

 

generate 블록은 복잡한 모듈 구조를 구현하는 데 사용될 수 있으며, 코드의 재사용성과 유지보수성을 향상시킬 수 있다. 그러나 generate블록을 사용할 때 주의할 점은 모듈 인스턴스 및 신호 선언에 대한 스코프 규칙을 잘 이해하고 사용해야 한다.

 


  • generate for문과 일반적인 for문의 차이점

 

  1. 실행 시점
    1. 일반적인 for문 : 실행 시점에서 루프가 반복되며, 반복문 내의 문장이 순차적으로 실행.
    2. generate for문 : 코드 컴파일 시점에 루프가 반복되며, 반복문 내의 generate 블록이 복제되거나 조건부로 실행.
  2. 적용 대상
    1. 일반적인 for문 : 주로 절차적인 동작을 수행하는 데 사용되며, 데이터 경로나 상태 머신을 구현하는 데 유용.
    2. generate for문 : 코드 생성과 제어에 사용되며, 코드의 구조를 생성하거나 파라미터화된 모듈 인스턴스를 생성하는 데 사용.
  3. 범위
    1. 일반적인 for문 : 반복문이 주로 시간 동작을 반복하므로, 시간적인 범위를 나타내는 존건식을 사용.
    2. generate for문 : 복제된 블록이나 생성된 모듈  인스턴스를 가지고 있으모로, 구조적인 범위를 나타내는 조건식을 사용.
  4. 병렬성 : 
    1. 일반적인 for문 : 병렬 실행을 지원하지 않는다. 루프 내의 문장은 순차적으로 실행된다.
    2. generate for문 : generate 블록 내에서 복제된 블록이 동시에 실행될 수 있으며, 병렬 실행을 지원.

generate for문은 주로 코드의 재사용성과 유연성을 높이기 위해 사용되는 반면, 일반적인 for문은 주로 데이터 경로 및 제어 경로를 구현하는 데 사용. 

 


module GenerateForExample;
  reg [7:0] data [3:0];

  generate
    genvar i;
    for (i = 0; i < 4; i = i + 1) begin : gen_block
      always @(posedge clk) begin
        data[i] <= data[i] + 1;
      end
    end
  endgenerate

endmodule
module ForExample;
  reg [7:0] data [3:0];

  always @(posedge clk) begin
    for (integer i = 0; i < 4; i = i + 1) begin
      data[i] <= data[i] + 1;
    end
  end

endmodule

위 두 코드 중 generate for문은 코드 컴파일 시점에서 루프를 반복하며 복제된 블록을 생성한다. 따라서 'gen_block'블록 내의 코드가 각각 별개의 블록으로 독립적으로 동작한다. 

 

반면, 일반적인 for문은 실행 시점에서 루프를 반복하며 코드가 순차적으로 실행된다. 

generate for문과 일반적인 for문은 컴파일러에서 해석되면

module GenerateForExample;
  reg [7:0] data [3:0];

  always @(posedge clk) begin
    data[0] <= data[0] + 1;
  end
  always @(posedge clk) begin
    data[1] <= data[1] + 1;
  end
  always @(posedge clk) begin
    data[2] <= data[2] + 1;
  end
  always @(posedge clk) begin
    data[3] <= data[3] + 1;
  end
endmodule
module ForExample;
  reg [7:0] data [3:0];

  always @(posedge clk) begin
    data[0] <= data[0] + 1;
    data[1] <= data[1] + 1;
    data[2] <= data[2] + 1;
    data[3] <= data[3] + 1;
  end

endmodule

과 같이 해석된다.

for문은 각각의 반복에서 always @(posedge clk)블록을 생성하지 않는다. 그러나 generate for문은 always @ (posedge clk)블록을 별도로 생성하고, 그 안에서 각각의 할당문을 사용하여 데이터 경로의 요소를 독립적으로 조작한다.

 

따라서 generate for문은 동일한 always @(posedge clk)블록 내에서 순차적으로 실행되는 것이 아니라, 별개의 always @(posedge clk)블록들에서 실행된다.