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

하만(Harman) 세미콘 아카데미 14일차 - Verilog HDL 설계(Verilog 문법, Verilog if-else, case, comparator 구현)

semicon_circuitdesigner 2024. 3. 26. 15:16

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


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


Continuous Assignment


  • Dataflow: 부울 연산과 연산자를 이용한 모델
  • 동작적 / 절차적 모델링: 모델 설계 알고리즘

1. Data Flow 코드와 구조 예시

  • D Flip-Flop
    module dff (input d, clk, rst, output reg q);
    	always @ (posedge clk)
        	if(rst)
            	q <= 1'b0;
            else
            	q <= d;
    endmodule //dff​
  • 3-Bit Counter
    module count3 (input clk, rst, ouput[2:0] q);
    	wire n1, n2;
        assign n1 = (q[0] ^ q[1]);
        assign n2 = (q[2] ^ (q[0] & q[1]));
        dff dff0(~q[0], clk, rst, q[0]);
        dff dff1(n1, clk, rst, q[1]);
        dff dff2(n2, clk, rst, q[2]);
    endmodule //count3​


3. Delays

  • Delay: 물리적인 요인으로 인해 동작 시 신호의 지연 발생
    • 저항, 온도, 전하의 이동 속도 등에 의해 발생
    • Delay 처리 코드 예시
    • Modeling Delays: assign #{2, 3, 5}
       - 2: Rise, 0 -> 1 변할 때 2ns의 delay
       - 3: Fall, 1 -> 0 변할 때 3ns의 delay
       - 5: Turn-off, ? -> z(off) 변할 때 5ns delay

Gate-Level Modeling


  • 논리게이트를 이용하여 디자인하는 과정
  • 게이트 종류: AND, NAND, OR, NOR, XOR, XNOR, BUF, NOT
  • 게이트에서도 delay 발생

 


Procedural Assignment


1. 절차블록

  • Initial 구문: 수행 중 한 번 동작
  • Always 구문: 수행 중 반복 동장

2. Initial 블록

  • time 0에서 시작
  • begin과 end 키워드를 통해 initial 구조를 묶을 수 있음 
  • module dff_tb(); reg rst, clk; initial begin #10 rst = 1'b1; //10ns delay 후 reset #20 rst = 1'b0; //20ns delay 후 reset end initial clk = 1'b0; ...​

 
3. Procedural Assignments

reg [7:0] my_bus;	//자료형이 reg, integer, real, time인 값만 가능
...
initial
begin		
	my_bus = 8'b11110000;
end

Blocking(<=) and Non-Blocking(=) Procedural Assignments


1. Delay가 있는 Blocking assignments

initial
begin
...
...
#5 e = 1;
...
...
end

5ns 딜레이 후 e가 1

2. Delay가 없는 Blocking assignments

initial
begin
...
...
a = 1;
...
...
end

 
3. 


실습 1: ASYNC, SYNC 동작 확인


  • A - SW0, B- SW1, CLK - SW2,K RST - SW3
  • A, B, R, Q 출력
  • R = 1
  • CLK 0 -> 1
  • A, B => R = 0
  • RTS = 1-> 0
  • 동작 확인 방법
    • A = 1, B = 1, R, Q 출력 확인
    • CLK 0 -> 1로 바꾸고 R, Q 출력 확인
    • RST 0 -> 1로 바꾸고 R, Q 출력 확인
    • RST 1 -> 0로 바꾸고 R, Q 출력 확인
    • CLK 0 -> 1로 바꾸고 R, Q 출력 확인
    • A, B를 바꿔 R = 0이 되게 하고 Q 출력 확인
    • CLK를 0 -> 1, 1->0 바꾸며 R, Q 출력 확인

1. my_dff 파일 생성 후 Add sources에 my_dff.v추가 후  A, B, CLK, RST는 입력으로, R, Q는 출력으로 설정
2. my_dff.v코드 작성

module my_dff(
    input RST, CLK, A, B,
    output reg R, Q
    );
    
always @(A, B)
    R = A & B;
    
always @(posedge CLK)
if ( RST == 1'b1)
    Q <= 1'b0;
else
    Q <= A & B;    

endmodule

 
3. open Elaborated Design - 포트 설정

 
4. Run Synthesis
5. Run Implemntation - 오류 발생
6. my_dff.xdc의 가장 아래에 set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets CLK_IBUF] 입력

 
7. Run Implementation 재실행
8. my_dff.v 파일 재수정

module my_dff(
    input RST, CLK, A, B,
    output reg R, Q
    );
    
always @(A, B)
    R = A & B;
    
always @(posedge CLK, posedge RST)
if ( RST == 1'b1)
    Q <= 1'b0;
else
    Q <= A & B;    

endmodule

 
9. Run Synthesis - Run Implementation - Generate Bitstream 다시 진행 후 실행 확인
 
10. 동작 확인
 


Procedural Timing Control


1. 타이밍 제어

  • #: Delay 기반 제어
    • 시간 단위는 상단에서 timescale로 설정
  • @: Event 기반 제어
  • wait: Level 기반 제어
    • wait(~)에서 ~가 1이 될 때까지 대기

2. 이벤트 기반 타이밍 제어

  • 논리값의 변화에 따라 Event 정의
  • 사용 예시: always@(a or b)
  • 괄호 내의 요소: sensitivity list
  • Async: CLK에 관계없이 동작
  • Sync: CLK에 따라 동작

3. 이벤트 기반 타이밍 제어를 이용한 D-type 플립플롭 모델링

  • Active low async clear
    always @ (posedge clk, negedge rst)
    	begin
        	if( rst == 1'b0 ) q <= 1'b0;
            else	q <= d;
        end​
  • Acrive high sync set
    always @ (posedge clk, negedge rst)
    	begin
        	if( rst == 1'b1 ) q <= 1'b0;
            else	q <= d;
        end​​
  • Active low async clear, active high CE
    always @ ( posedge clk, negedge rst)
    	begin
        	if(rst == 1'b0)	q <= 1'b0;
            else if (ce == 1'b1)	q <= d;
    end​
  • Active low async reset, active high CE
    always @ ( posedge clk )
    	begin
        	if(rst == 1'b0)	q <= 1'b0;
            else if (ce == 1'b1)	q <= d;
    end​

조건문: if-else


  • always 구문 내에서 사용
  • always@(sel, a, b)
    	if (sel == 1)
        	y = a;
        else
        	y = b;
  • 여러줄에 실행 내용 작성 시 C의 {}처럼 begin~~end로 묶음 가능
  • 할당되지 않은 값에 대해 불안정한 동작을 유발할 수 있으므로 명확한 정의 필요
  • if-else if 구문
    • 예시 1
      always @ (...)
      begin
      ...
      ...
      	if (<expression>)
          	sequential statement(s);
          else if(<expression>)
          	sequential statement(s);
          else if(<expression>)
          	sequential statement(s);
          else
          	default statement(s);
      ...
      ...
      end​​
    • 예시 2
      always@*
      if	(sel == 2'b00) y=a;
      else if	(sel == 2'b01) y=b;
      else if	(sel == 2'b10) y=c;
      else				   y=d;​
    • 예시 3
      always@*
      if	(sel == 2'b00) y=a;
      else if	(sel == 2'b01) y=b;
      else if	(sel == 2'b10) y=c;
      else if	(sel == 2'b11) y=d;​​
    • 예시 4
      always@*
      if	(sel == 2'b00) y=a;
      else if	(sel == 2'b01) y=b;
      else if	(sel == 2'b10) y=c;
      else if	(sel == 2'b11) y=d;
      else	y=a;​​​
    • 예시 5
      always@*
      if	(sel == 2'b00) y=a;
      else if	(sel == 2'b01) y=b;
      else if	(sel == 2'b10) y=c;
      else if	(sel == 2'b11) y=d;
      else	y=1'b0;​​​

 


조건문: case


  • always 구문 내에서 사용
  • begin~end구문 내에서 선언
  • 예시 
  • always@(inputs....) begin case (expression) <choice 1>: <statement1>; <choice 1>: <statement2>; <choice 1>: <statement3>; default: <default statement>; endcase end​

 


실습 2: Comparator 구현


  • input: A[1:0], B[1:0] / output: E(LED_R), Q(LED_G), L(LED_B)
  • if (A<B) -> L = 1, G = 0, E = 0
  • if (A=B) -> L = 0, G = 0, E = 1
  • if (A>B) -> L = 0, G = 1, E = 0
  • 설계요구사항
    • MODULE 선언부
      input: A[1:0], B[1:0]
      output: L, G, E
    • Design
      always문 사용, if-else문 사용, 비교연산자 사용

1. vivado - my_comp 파일 생성
2. add source- create file로 my_comp 생성 후 input, output 설정

 
3. my_comp.v 코드 작성

module my_comp(
    input [1:0] A,
    input [1:0] B,
    output reg L,
    output reg G,
    output reg E
    );
    
always @(A, B)

begin

    L = 1'b0;
    G = 1'b0;
    E = 1'b0;
    
    if (A<B)
        L = 1'b1;
    else if (A>B)
        G = 1'b1;
    else if (A==B)
        E = 1'b1;
end

endmodule

 
4. open elaborated design - 포트 설정

 
5. 저장 후 run implementation - ... - Device program 후 작동 확인
 


실습 3: SW to 7-segment 구현


  • 7세그먼트: Digilent의 pmodSSD 사용

 

  • 설계 요구사항

  • Module 선언부
    input SW[1:0] -> 보드의 BTN1, BTN0을 입력으로 사용
    output CA
    output AN[7:0]

1. my_seg파일 생성 - Add sources - Create file

2. 코드 작성

module my_seg(
    input [1:0] SW,
    output CA,
    output reg [7:0] A
    );
    
assign CA = 1'b0;

always@(SW)
begin

    case(SW)
        2'b00: A = 8'hfc;
        2'b01: A = 8'h60;
        2'b10: A = 8'hda;
        2'b11: A = 8'hf2;
        default: A = 8'h00;
    endcase

end

 
3. 포트 설정

 
4.나머지 과정 수행 후 동작 확인


과제: stopwatch 구현해보기