본문 바로가기
HW Design/1. Verilog HDL Basic

[Reusable Code] 2. 생성문

by 한PU 2024. 1. 16.
728x90
반응형
  • generate 문
    • 코드 블록을 조건부 or 반복적으로 생성하기 위함.
    • concurrent 코드 블록에서만 사용 가능
      • always block, initial block 내에 포함 불가능.
    • generate 키워드 + if문, case문, for loop
      • if, case generate 문
        • 조건부로 코드를 생성
      • for generate 문
        • 반복적으로 코드를 생성
    • generate block 내부에 verilog 코드 작성 가능
      • always block
      • 모듈 인스턴스화
      • 기타 generate 문
    • Verilog 2001 Standard 에 도입 됨.
      • 1995 에서는 사용 불가

Generate For loop in Verilog

  • generate block 내에서 for loop를 사용하여 여러 인스턴스를 반복적으로 생성 가능.
  • 일반적으로 규칙적, 반복적 구조를 가진 HW를 설명할 때 generate for loop 접근 방식을 사용.
    • 단일 bus를 사용하여 제어하려는 여러 RAM 모듈 설명.
      • 모듈을 수동으로 인스턴스화 X
        • generate block 사용
// loop 변수 선언
genvar <name>;

// generate block
generate
    for (<initial_condition>; <stop_condition>; <increment>) begin
        // code here
    end
endgenerate
  • for loop 구문과 거의 비슷.
    • 차이점 1
      • genvar type으로 루프 변수 선언.
    • 차이점 2
      • always block등의 일반 절차 블록이 아닌 generate block 내에서 루프를 선언.
        • 코드의 기본 동작을 변경하므로 중요.
          • normal for loop : 컴파일러에게 단일 인스턴스를 생성하는 지시를 여러 번 실행하도록 함.
          • generate for loop : 컴파일러에게 여러 인스턴스를 생성하라고 지시.
        • 2 bits vecter에 데이터 할당 예시.
          • 기능은 동일하지만, 구조는 다르다.
// normal for loop
always @(posedge clock) begin
    for (i = 0; i < 2; i = i + 1) begin
        sig_a[i] = 1'b0;
    end
end

// generate for block
generate
    for (i = 0; i < 2; i = i + 1) begin
        always @(posedge clock) begin
            sig_a[i] = 1'b0;
        end
    end
endgenerate
  • 코드를 단순하게 펼쳐보면...
// normal for loop
always @(posedge clock) begin
    sig_a[0] = 1'b0;
    sig_a[1] = 1'b0;
end

// generate for block
always @(posedge clock) begin
    sig_a[0] = 1'b0;
end

always @(posedge clock) begin
    sig_a[1] = 1'b0;
end

Verilog Generate For Example

  • 동일한 bus에 연결된 3개의 RAM 모듈 배열 사용.
    • 각 RAM 모듈에는 write enable port, 4-bit address input, 4-bit data input이 존재.
      • 모든 신호는 동일한 bus에 연결됨.
    • 각 RAM에는 각 RAM 블록과 독립된 4-bit data output bus와 enable signal 존재.
  • 회로도
  • 3 bit 벡터를 선언하고 RAM enable ports에 연결하는 데 사용할 수 있다. 이후 loop 변수 값에 따라 각 RAM 블록에 다른 bit를 연결할 수 있다.
  • data output bus
    • 12 bit vector
      • read data output을 벡터의 다른 4-bit slices에 연결할 수 있음.
    • 3개의 4-bit vector
      • loop 변수를 사용해 배열의 요소에 각각 할당.
// rd data 배열
wire [3:0] rd_data [2:0];

// enable signal vector
wire [2:0] enable;

// loop 변수
genvar i;

generate
    for (i = 0; i <= 2; i = i + 1) begin
        ram ram_i (
            .clock    (clock),
            .enable   (enable[i]),
            .wr_en    (wr_en),
            .addr     (addr),
            .wr_data  (wr_data),
            .rd_data  (rd_data[i])
        );
    end
endgenerate
  • 합성 이후 회로

If Generate Statement in Verilog

  • 디자인에 코드 블록을 조건부로 포함.
  • 특정 조건에서만 사용하려는 코드가 있는 경우 사용 가능.
    • production build 와 debug build를 나눈 경우 등
generate
    if (<condition1>) begin
        // code here
    end
    else if (<condition2>) begin
        // code here
    end
    else begin
        // code here
    end
endgenerate
  • if문과 거의 비슷.
    • 차이점
      • generate if statement
        • 실제로 컴파일러에게 일부 조건에 따라 코드 블록의 인스턴스를 생성하라고 지시.
        • 하나의 분기를 제외한 다른 분기는 컴파일에서 제외.
          • 결과적으로, 설계 내에서는 분기 중 하나만 사용 가능
      • if statement
        • 전체 if문 컴파일
          • 각 분기가 실행될 수 있음.
        • 시뮬 중에 조건을 평가하여 실행할 분기를 결정.

Verilog Generate If Example

  • 4-bit 카운터의 결과 값에 대한 테스트 함수 작성.
    • 테스트이므로 debug build 일때만 활성화.
      • debug version 빌드를 위해 parameter 사용
    • production version에서는 카운터 출력을 접지에 연결
// 빌드 컨트롤을 위한 parameter
parameter debug_build = 0;

// 카운터 조건부 생성
generate
    if (debug_build) begin
        // 카운터 code
        always @(posedge clock, posedge reset) begin
            if (reset) begin
                count <= 4'h0;
            end
            else begin
                count <= count + 1;
            end
        end
    end
    else begin
        initial begin
            count <= 4'h0;
        end
    end
endgenerate

  • debug_build = 1 일때
    • 4-bit 카운터 회로 생성

  • debug_build = 0 일 때
    • 모든 bit 접지.

Case Generate in Verilog

  • 디자인에 코드 블록을 조건부로 포함하기 위해 사용.
  • 기본적으로 generate if 문과 동일한 기능 수행.
generate
    case (<variable>)
        <value1> : begin
            // branch
        end
        <value2> : begin
            // branch
        end
        default : begin
            // branch
        end
    endcase
endgenerate
  • case 문과 거의 동일.
    • 차이점
      • generate case statement
        • 실제 verilog 컴파일러에게 조건에 따라 코드 블록의 인스턴스를 생성하라고 지시.
        • 분기 중 하나만 컴파일, 나머지 제외.
      • normal case statement
        • 전체 컴파일 이후 각 분기 실행.

Verilog Generate Case Example

  • if generate 문과 동일 예시.
// 빌드 컨트롤을 위한 parameter
parameter debug_build = 0;

generate
    case (debug_build)
        1 : begin
            // 카운터 code
            always @(posedge clock, posedge reset) begin
                if (reset) begin
                    count <= 4'h0;
                end
                else begin
                    count <= count + 1;
                end
            end
        end
        default : begin
            initial begin
                count <= 4'h0;
            end
        end
    endcase
endgenerate

  • 변수 1일 때

  • 변수 0일 때
728x90
반응형