RTL Design/Verilog RTL 설계
Verilog RTL 설계 (6월 12일 - 1) - Verilog 넌 누구냐?
유로 청년
2024. 6. 12. 20:27
1. Verilog가 어떻게 생겼을까?
- AND Gate에 대해서 Verilog로 작성하면 다음과 같이 작성할 수 있다.
- 환경) basys3 개발 보드
module and_gate(
input a, b,
output reg q
);
always @(a, b)begin
case({a,b})
2'b00: q = 0;
2'b01: q = 0;
2'b10: q = 0;
2'b11: q = 1;
endcase
end
endmodule
위 코드에 대해서 하나씩 명령어를 보면서 간략하게 생각해보자.
1.1. Q) Module이란 무엇인가?
- Module은 Verilog에서 하나의 기능을 갖는 블록 단위를 의미한다.
- 하나의 모듈(Module)에는 하나 이상의 입력과 출력을 갖는다.
- 일반적으로 Module은 디지털 논리 회로에서 Gate, Register, Counter, Memroy 등을 나타내기 때문에 Module은 논리 회로에서 논리 동작을 정의한다.
- Module안에 또 다른 Module이 존재할 수 있으며, 이 때, 안에 있는 Module을 Sub Module이라 한다.
1.2. Module의 기본 구조
- Module의 기본 구조는 아래와 같다.
- 모듈의 시작과 끝, 범위는 Module (name of Module) ~ endModule 로 정의한다.
- 소괄호 속에는 주로 Module의 입력, 출력 변수를 정의한다.
- 소괄호 속에 정의된 변수들은 reg 자료형으로 형 변환이 없다면 wire 자료형으로 인식한다.
module and_gate ( );
endmodule
- AND Gate는 입력 비트 단자(a, b)와 출력 비트 단자(q)를 사용하기 때문에 아래와 같이 선언했다.
- 입력 비트 단자 : 2개의 입력 비트 단자에 대해서 a, b 변수명으로 지정
- 출력 비트 단자 : 1개의 출력 비트 단자에 대해서 q 변수명으로 지정
module and_gate (
input a, b,
output reg q );
1.3. reg 자료형과 wire 자료형이란 무엇인가?
- Verilog 에는 대표적인 자료형으로 reg 자료형과 wire 자료형이 있다.
- wire 자료형은 다음과 같은 특성을 갖는다.
▶ 속해있는 모듈 뿐만 아니라 다른 모듈간에 인터페이스가 가능하다.
▶ 주로 모듈 간에 데이터 전달하는 목적으로 사용한다. - reg 자료형은 다음과 같은 특성를 갖는다.
▶ 속해있는 모듈에서만 접근이 가능하고, 외부 모듈와의 인터페이스는 불가능하다.
▶ sequential logic component내에서 상태를 저장하는 목적으로 사용한다.
1.4. 그럼 왜 출력 변수 q에 대해서 wire 자료형에서 req 자료형으로 형 변황을 했는가?
왜 출력 변수 q를 wire 자료형에서 req 자료형으로 형변환했냐하면 바로 아래와 같이 always내에서 대입연산자의 l-value 변수로 사용되기 때문이다.
always @(a, b)begin
case({a,b})
2'b00: q = 0;
2'b01: q = 0;
2'b10: q = 0;
2'b11: q = 1;
endcase
end
- always 내부의 문법에 대해서 아직 자세히 볼 필요 없고, 출력 변수 q가 대입연산자 (=)에서 l-value로 활용되었음 확인할 수 있다.
- Verilog에서 대입 연산자의 l-value는 reg 자료형을 가져야 하며, wire 자료형은 허용하지 않는다.
1.5. Always @( ) begin ~ end 는 뭐하는 기능인가?
Always은 특정 조건에 만족하거나 특정 변수(Sensitive variable)에 변화가 발생하면 반복적으로 실행하는 코드이다.
Always 블록은 다음과 같은 구조와 형태를 갖는다.
module and_gate (
// 입력 변수 : a, b
// 출력 변수 : q
// 소괄호안에 정의된 변수는 기본적으로 wire 자료형을 갖는다.
input a, b,
output reg q );
// sensitive variable에 변화가 발생하면
// 반복적으로 수행한다.
always @( sensitive variables ) begin
end
endmodule
- AND Gate의 입력 단자인 a, b을 Sensitive variable로 설정하면 Always 블록은 sensitive variable로 a, b를 인식하고, 감시하다가 a 나 b에서 값의 변화가 발생하면 Always 내 case문을 실행한다.
- 따라서 AND Gate의 Truth table에 맞게 case문을 작성하면 다음과 같이 작성할 수 있다.
module and_gate (
input a, b,
output reg q );
// Always의 sensitive variable로 a,b로 설정.
// a나 b에서 값의 변화가 감지되면 Always내에 있는 case문을 실행.
always @(a, b) begin
case({a, b})
2'b00: begin s=0; c=0; end;
2'b01: begin s=1; c=0; end;
2'b10: begin s=1; c=0; end;
2'b11: begin s=0; c=1; end;
endcase
end
endmodule
1.6. 2'b00: begin q=0; end; 와 같은 형태는 의미를 무슨 의미를 의미하는가?
- case({a, b}) ~ endcase :
- sensitive variable a, b의 값 변화가 있을 경우 해당 case문을 실행
- case문은 case({ }) ~ endcase 범위를 갖는다. - 2'b00: begin q=0; end; :
- 각 숫자와 문자들은 다음과 같은 뜻을 갖는다.
- 2 : sensitive 변수의 비트 수를 의미
- b : sensitive 변수의 자료형이 binary임을 의미
- 00 : a = 0이고, b = 0이라면 해당 case를 실행하라는 의미
- begin ~ end; : C언어에서 { } 와 유사한 역활
: 만약 구 개의 구문이 아닌 하나만 적혀 있었다면 begin과 end를 사용하지 않아도 된다.
2. AND Gate에 대해서 소스 코드를 작성하고, 어떻게 실행하고, 결과 값을 확인하는가?
- Source code을 실행하는 과정은 다음과 같은 단계를 거친다.
- 1단계) 소스 코드를 저장한다.
- 2단계) Run Simuation 버튼 실행
- 3단계) 입력 변수(값)에서 오른쪽 버튼 누르고, Force constant 혹은 Force Clock를 누른다.
- Force constant는 입력 변수 (단자, 값)으로 상수 값 (0 or 1)을 대입
- Force Clock는 Clock signal에 맞춰 값과 Duty cycle, Period 값을 조정하여 대입
- 4단계) 출력 범위를 설정한 뒤, 출력
3. AND Gate 출력 시뮬레이션
- 아래 출력은 AND Gate의 Truth table과 동일하게 출력 되었음을 확인했다.
- 주의) 출력을 확인하고, 절대 저장하지 말 것!
출력을 저장하면 다음 시뮬레이션에서 설정값이 저장된 상태로 출력이 반영되기 때문에 절대 저장 하지 말것!