(https://fpgatutorial.com의 내용을 정리함.)
1. Structuring Verilog Code : Verilog의 구조
Verilog HDL 코딩은 HW 디자인입니다. C, C++, Python 등의 SW 프로그래밍과 많은 부분에서 차이가 있습니다.
Verilog HDL의 핵심 중 하나는 컴포넌트(Component) 혹은 모듈 (Module)입니다.
(컴포넌트 참고링크 : http://wiki.hash.kr/index.php/%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8)
서로 다른 여러 컴포넌트의 동작을 설명해야 하며, 이후에는 서로 연결하는 작업이 필요합니다.
가장 중요한 점은 컴포넌트가 어떻게 작동하는지 알아야 시스템에 써먹을 수 있다. 는 것입니다.
저는 앞으로 설명할 때 모듈이라고 말하겠습니다. Verilog 의 키워드이기 때문입니다
module
키워드 'module'
- Verilog에서 구조를 나타내는 키워드
- module 내부에서 설명하는 동작을 정의한다.
- VHDL의
entity
아키텍쳐와 같다.
module 구문
module (
// 여기에서 parameters를 선언 가능
parameter <parameter_name> = <default_value>
)
<moudle_name> (
// 모든 IO (Input, Output)이 여기에서 정의됨
<direction> <data_type> <size> <port_name>
);
// 기능적, 구조적 RTL code 입력
endmodule
<module_name> 설명
- 디자인할 모듈의 이름을 적는다.
- 하나의 파일에서 여러 개의 모듈을 선언 가능
- 하나의 파일에 하나의 모듈을 선언하는 것이 좋다.
- 모듈 이름과 파일 이름을 같게 하는 것이 좋다.
- 여러 컴포넌트를 관리하기에 용이하기 때문이다.
// 설명
- 주석 기호
- C와 동일하다.
Verilog 1995 Modules
모듈 선언 구문은 2001년에 표준으로 자리하였습니다.
Verilog 1995 표준으로 코드를 작성할 때 아래와 같은 유의 사항이 있습니다.
- 초기 모듈 선언에서 포트 이름만 정의
- 이후 모듈 본문에서 포트 direction, data type, size 등을 정의한다.
- 모듈 parameters도 본문에서 정의한다.
Verilog 1995 module 구문 예시
module <module_name> (
// 모든 IO가 여기에서 정의됨.
<port_name>
);
// Parameters 정의.
parameter <parameter_name> = <default_value>;
// 여기에서 IO 정의 완성.
<direction> <data_type> <size> <port_name>;
// 기능적, 구조적 RTL code 작성.
endmodule
이후 서술하는 Verilog 2001 표준과 비교하면 차이점을 쉽게 알 수 있습니다.
Parameters in Verilog Modules
Parameters는 상수의 지역적 형태인데요. (local form of constant)
C언어의 파라미터 선언과 비슷합니다.
Module 구성에 사용하는데, 아래와 같은 예시에서 사용합니다.
- 모듈을 인스턴스화 할 때
- parameters에 값을 할당하여 모듈 동작을 구성
- 범위 제한
- 동일한 모듈을 여러 번 호출하고, 매번 다른 값을 parameters에 할당할 수 있다.
parameters 선언은 필수가 아니여서 대부분 모듈에서 포함할 필요가 없습니다.
하지만, parameters를 사용하면 더욱 generic한 모듈 인터페이스를 작성할 수 있습니다.
다시말해, reusing이 쉬워집니다.
모듈에서 parameters를 선언 후 다른 변수처럼 동일한 방식으로 사용할 수 있습니다.
하지만, parameters는 상수임을 유의해야 합니다.
- 읽기만 가능, 수정 불가능
- 정의될 때만 value를 할당 가능
Parameters에 대한 더 많은 자료는 아래 링크에서 찾아볼 수 있습니다.
(참고 링크 : https://fpgatutorial.com/verilog-generate/)
시간이 될 때, 위 링크에 대한 내용도 포스팅 해보겠습니다.
Functional Code
모듈 구문의 IO 포트 선언 이후의 내용들입니다.
// 기능적, 구조적 RTL code 입력 이라고 주석 처리된 부분을 의미합니다.
일반적으로 RTL coding을 사용하나, 아래와 같은 항목들도 사용 가능합니다.
- Structural code
- Describe primitives
코드 작성을 마치면 `endmodule` 키워드를 사용하여 끝냅니다.
Verilog Module Ports
모듈에서 IO (Input, Output)를 정의하기 위해 Ports를 선언합니다.
아두이노 등의 기존 전자 부품의 PIN과 동일한 역할을 합니다.
P15에 input ~~ 를 선언한다. 의 개념입니다.
일반적인 Port 구문
<direction> <data_type> <size> <port_name>
위 코드 블럭을 하나씩 설명하겠습니다.
<port_name>
각 port에 고유한 이름을 부여합니다.
<direction>
방향성을 정의합니다.
input, output, inout 의 세 종류 중 정의합니다.
<data_type>
데이터 타입을 선언합니다.
일반적으로 D f/f을 포함하는 reg 타입과
port끼리 연결해주는 wire 타입이 있습니다.
<size>
vector type의 포트에 대해 여러 bit를 선언할 수 있습니다.
[MSB:LSB] 의 형태를 통용적으로 사용하고 있습니다.
Port 구문 예시
input wire [7:0] example_in ;
입력 방향으로 8bit의 신호를 갖는 example_in 이라는 이름의 wire 타입 Port 입니다.
생각보다 쉽습니다.
Reg and Wire Types in Verilog
reg type과 wire type은 Verilog를 처음 접하는 이들에게는 조금 생소한 표현입니다.
이 둘을 비교하며 좀 더 알아보겠습니다.
wire type
간단한 point to point 연결일 때 선언하는 신호입니다.
전통적인 회로의 wire와 같습니다. 빵판에서 IC 칩의 point to point를 할 때 점프선 맞습니다.
그렇기에, wire type은 data를 drive 하거나 value를 저장할 수 없습니다.
Combinational logic circuits(조합 회로)를 모델링할 때 주로 사용하며,
input, output에 대해 전부 선언 가능합니다. (생각보다 헷갈려요.)
reg type
data를 능동적으로 drive할 때 선언하는 신호입니다.
전통적인 회로의 Flip-Flop과 같습니다. 데이터 저장이 가능합니다.
Sequential logic circuits를 모델링할 때 주로 사용하며,
아래와 같은 특징을 갖습니다.
- always block 내에서만 사용
- always block에 대한 내용은 아래 링크를 참고해주시기 바랍니다.
- 2024.01.10 - [HW Design/1. Verilog HDL Basic] - [Using the Always Block] 1. Always block 이란?-
- output에 대해서만 선언 가능합니다.
data type 생략시 default는 wire type입니다.
글을 이쁘게 수정하는게 쉽지 않네요.
도움 되셨으면 좋겠습니다. 모르는 내용이 나와도 넘어가고 쭉쭉 공부하시다보면 자연스레 알게될 것입니다.
감사합니다.
다음 글 :
2024.01.02 - [HW Design/1. Verilog HDL Basic] - [Basic Verilog Module] 2. 모듈 인스턴스화
'Verilog HDL > 1. Verilog HDL Basic (문법)' 카테고리의 다른 글
[Basic Verilog Module] 4. 예제 풀이 (1) | 2024.01.02 |
---|---|
[Basic Verilog Module] 3. 베릴로그 모듈 예시 (2) | 2024.01.02 |
[Basic Verilog Module] 2. 모듈 인스턴스화 (2) | 2024.01.02 |
[Verilog Tutorial] 1 - Introduction (2) | 2023.10.04 |
[LINUX] 리눅스 기본 명령어 알아보기 (0) | 2023.09.28 |