[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 생성
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 후 작동 확인
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. 실행 화면
[화면 설명]
[ Parameter 사용 ]
1. parameter 선언
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 생성
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 후 결과
7. Elaborated Design
8. Run Synthesis - Run Implementation
9. 작동 영상