[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

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;
- 예시 1
조건문: 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문 사용, 비교연산자 사용
- MODULE 선언부
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 구현해보기