하만(Harman) 세미콘 반도체 설계 과정/Verilog를 이용한 RTL 시스템 반도체 설계

하만(Harman) 세미콘 아카데미 18일차 - Verilog HDL 설계(Clock과 Reset, 카운터 설계, 테스트벤치, 검증)

semicon_circuitdesigner 2024. 4. 1. 12:55

[2024.04.01.월] 인천인력개발원 하만 세미콘 아카데미


Verilog를 이용한 RTL 시스템 반도체 설계


Clock과 Reset


  • Clock(clk, 클록)
    • 디지털 시스템에서 데이터 처리의 타이밍을 제어하는 주기적인 신호
    • 주파수, 주기를 통해 신호의 반복속도, 시간 등을 나타냄
  • Reset(rst)
    • 디지털 시스템을 초기 상태로 되돌리는 데 사용
    • Synchronous Reset: 클록 신호에 동기화되어 작동 - 리셋 시 다음 클록 엣지에서 시스템 초기화
    • Asynchronous Reset: 클록 신호와 무관하게 즉시 작동 - 빠른 리셋이 가능하지만 동기화 문제 발생 가능
  • Flip-Flop(FF)
    • 한 비트의 이진 정보를 저장하는 메모리 단위
    • 클록 신호에 의해 제어
    • 입력 데이터를 기반으로 두 가지 안정된 상태 중 유지 가능
    • SR(Set-Reset) Flip-Flop: Set과 Reset 입력 신호를 가지는 플립플롭
    • D(Data) Flip-Flop: 데이터(D)와 클록(Clock) 입력 신호를 가지는 플립플롭

 


실습 1: Counter 설계


  • 입력
    • Clock: 125MHz - H16포트 사용
    • RST - Button 사용
    • DIR(Direction) - Switch 사용
  • 출력: Output[2:0] LED R, G, B
  • 설계 요구사항
    • CLK의 상승 에지마다 up_down 신호가 high면 32bit counter 증가, low면 감소하는 회로 설계
    • 상위 8bit를 LED를 통해 출력 동작 확인

1. "my_cnt" Project 생성
2. Add Source로 my_cnt.v 생성

LED output은 버스로 선언

3. open elaborated design
4. run implementation
5. generate bitstream
6. H/W manage-program device
 
1. 파일 생성 후 input, output 설정
2. cnt를 reg로 선언 후 동작 코드 작성

  • always구문 내: 카운트 경우 분리(리셋, 방향 등 버튼에 따른 동작 분리)

 
3. 저장 후 Open Elaborated Design

4. 포트 설정

 
5. Run Synthesis - Generate Bitstream - Program Device 후 작동 확인

LED가 카운터와 연동되어 동작

 


Verilog Loop문


1. 루프문: forever, repeat, while, for

  • forever: 끝없이 반복하는 동작
  • repeat: 정해진 수만큼 반복
  • while과 for문은 C언어와 동일
    //forever문
    forever #10 clk = ~clk;
    
    //repeat문
    repeat(256)
    begin
    	statement
    end    
    
    //while문
    while( en==1'b0 )
    	begin
        	statement
        end
    
    //for문
    for(i = 0; i<4; i=i+1)
    	statement​

 


Verilog Testbenches [검증]


  • Testbench(테스트벤치): Verilog HDL을 사용하여 디지털 회로의 설계 검증 수행에 사용되는 테스트 환경
  • 테스트벤치 구성요소
    • 모듈 선언: module testbench; 등으로 테스트벤치 모듈 시작
    • 테스트 대상 인스턴스
    • 테스트 벡터 생성: 초기화 블록('initial')을 사용하여 시뮬레이션에 사용될 입력값 생성
    • 결과 모니터링: $monitor, $display, $wirte등의 시스템 태스크로 시뮬레이션 중의 변수, 신호 값 출력 및 모니터링
    • 시뮬레이션 제어: 시뮬레이선의 시작과 끝을 제어하기 위해 initial 블록 내에서 $stop, $finish 시스템 함수 사용
  • 테스트벤치 예제
    module testbench;
        // 테스트할 모듈의 입력 및 출력 신호 선언
        reg a, b;
        wire sum, carry;
    
        // 테스트할 모듈의 인스턴스화
        adder uut (
            .a(a), 
            .b(b), 
            .sum(sum), 
            .carry(carry)
        );
    
        // 초기화 블록으로 테스트 벡터 제공
        initial begin
            // 입력값 초기화
            a = 0; b = 0;
            #10; // 10 시간 단위 지연
            
            a = 0; b = 1;
            #10;
    
            a = 1; b = 0;
            #10;
    
            a = 1; b = 1;
            #10;
    
            // 시뮬레이션 종료
            $finish;
        end
    
        // 출력 모니터링
        initial begin
            $monitor("시간=%g, a=%b, b=%b, 합=%b, 캐리=%b", $time, a, b, sum, carry);
        end
    endmodule​

실습 2: 카운터 검증


1. my_cnt.xpr open project
 
2. Add Source - Add or create simulation sources

 
3. Create File - 파일 생성

카운터 테스트벤치 파일 생성

 
4. Input, Output 설정 없이 Ok 클릭

 
5.  simulation source 생성

 
6. my_cnt_tb파일을 열어 시간 스케일 확인

 
7. my_cnt.v 파일의 모듈 파트를 복사하여 my_cnt_tb.v에 붙여넣기

 
8. reg와 wire 선언

 
9. 검증을 위한 코드 작성(. 뒤의 이름은 my_cnt에서 선언된 신호, 괄호 내의 이름은 테스트벤치에서 사용할 것)

 
10. falling edge를 만들기 위한 코드 작성

 
11. Clock 신호를 만들기 위한 코드 작성

 
12. DIR 신호를 만들기 위한 코드 작성

[전체 코드]

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2024/04/01 12:17:35
// Design Name: 
// Module Name: my_cnt_tb
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module my_cnt_tb();

reg RST, CLK, DIR;
wire[2:0]LED;

my_cnt uut(
    .RST    (RST),
    .CLK    (CLK),
    .DIR    (DIR),
    .LED    (LED)
    );
    
initial begin
    RST = 1'b1;
    #200;
    RST = 1'b0;
end //initial reset

initial CLK = 1'b0;
always #10 CLK = ~CLK;
    
initial begin
    DIR = 1'b0;
    wait (RST == 1'b0);
    #300;
    DIR = 1'b1;
    #300;
    DIR = 1'b0;
end
    
endmodule

 
13. Save 후 sources에 파일 명 (1) 생성 확인

 
 
14. Run Simulation - Behavioral Simulation

 
15. 실행 화면

 
[화면 설명]

우측 창의 줌아웃을 통해 전체 클록 확인 가능
축소를 통해 나타나는 화면
에지 이동 가능
왼쪽 버튼으로 화면 리셋

 

1마이크로초로 변경 후 실행 시
시간 변경 시 나타나는 클록

 

cnt우클릭 - radix - signed decimal로 변경 시 신호에 부호가 있는 숫자 표현

 

카운터가 아래로 갈수록 빠르게 정상작동 확인 가능

[ Parameter 사용 ]

1. parameter 선언

parameter로 clk_period를 선언하여 오른쪽 그림과 같이 사용 가능

 
2. 정상 출력 확인


실습 3: 1Sec Counter


  • 설계 요구사항
    • RST = 1이면 LED OFF
    • RST = 0이면 LED를 1초마다 ON/OFF
  • 설계 참고사항: 내부 카운터를 설계하여 1/2초마다 enable되는 신호 생성 -> enable 신호를 이용하여 출력을 반전시키는 회로 설계

1. my_1sec 프로젝트 생성
2. Add Sources - Add Design Sources - Create New File - input RST, CLK, output LED

 
 
3. my_1sec.v 파일 열어 코드 작성(parameter clk_freq = 125_000_000;)

`timescale 1ns / 1ps

module my_1sec(
    input RST,
    input CLK,
    output LED
    );
parameter clk_freq = 125_000_000;

reg enable;
reg [31:0] cnt;

always @(posedge CLK)
begin
    if (RST) 
        begin
        cnt <= 32'd0;
        enable <=1'b0;
        end 
    else 
        begin
        if (cnt == (clk_freq-1))
            begin
            cnt <= 32'd0;
            enable <= 1'b1;
            end
        else
            begin
            cnt <= cnt + 1;
            enable <= 1'b0;
            end
    end //if reset
end //always

always @(posedge CLK)
begin
    if(RST)
        LED <= 1'b0;
    else if(enable)
        LED <= ~LED;
end

endmodule

 
4. Add Source - Add or create simulation sources - my_1sec_tb.v 생성

Finish 클릭 후 입출력 설정 없이 OK

 
5. my_1sec_tb.v 코드 작성

module my_1sec_tb();
parameter CLK_PED = 10.0;

reg reset, clk;
wire dout;

my_1sec #( .clk_freq(10))	//클록 주파수를 10Hz로 바꾸는 코드
    uut(
    .RST    (reset),		//신호 이름 적기
    .CLK    (clk),
    .LED    (dout)
    );
    
initial begin
    reset = 1'b1;
    #(CLK_PED*10);
    reset = 1'b0;
end

initial clk = 1'b0;
always #(CLK_PED/2) clk = ~clk;

endmodule

 
6. Run Simulation 후 결과

클록 주파수를 10으로 설정하여 0~9까지 진행 후 초기화

 
7. Elaborated Design

8. Run Synthesis - Run Implementation

포트 설정

 
 
9. 작동 영상