이 포스팅은 제 개인적인 공부를 저장 및 복습하기 위해서 올리는 글입니다. 개인적인 정리기 때문에 저의 잘못된 이해가 섞여있을수도 있는 점 알려드립니다. 너무 맹신하지는 말아 주시기 바랍니다.
모듈 가져오기(instantiation)
이제 반가산기를 기본 요소로 모듈 가져오기 (instantiation)를 해서 전가산기(full adder)를 선계하는 구조적 설계의 예를 보인다. 이미 설계된 모듈을 가져오는 (instantiate) 방법은 다음과 같이 위치에 의한 연결(positional association)를 하는 내연적 (implicit) 방법과 이름에 의한 연결 (named association)을 사용하는 외연적(explicit) 방법이 있다.
내연적 방법 (포트 순서 즉 의치에 의해서 연결)
아래의 코드에서 u0, u1, 및 u2는 가져온 모듈에 이름을 부여한 것이다.
module full_adder(ci, a, b, co, s)
input ci, a, b;
output co, s;
wire ci, a, b, co, s;
wire s, c1, c2; //full_adder 내부의 포트.
half_adder u0 (ci, a, c1, s1); //half_adder는 반가산기
half_adder u1 (s1, b, c2, s);
or u3 (co, c1, c2);
endmodule
외연적 방법 (이름에 의해서 연결)
전가산기를 외연적인 방법으로 설계하면 다음과 같다.
module full_adder(ci, a, b, co, s)
input ci, a, b;
output co, s;
wire ci, a, b, co, s;
wire s1, c1, c2; //중간 wires
half_adder(.a(ci), .b(a), .c(c1), .s(s1))
half_adder(.a(s2), .b(b), .c(c2), .s(s));
or(co, c1, c2);
endmodule
위에서 .a(ci)의 의미를 반가산기의 a 포트에 전가산기 포트 ci를 연결하라는 뜻이다. 이름을 관련지었을 때는 그들이 나타나는 순서에 무관하다. 즉 c와 s의 위치를 바꾸어 half_adder(.a(ci), .b(a), .s(s1), .c(c1))으로 고쳐도 상관없다. abcs라는 순서 정해져있어서 순서를 바꿔도 상관없는 듯하다. 그래서 이름에 의한 연결이라고 하는 것 같다.
포트 연결 규칙
포트 연결 (port connection)에는 다음의 규칙을 따라야 한다.
입력 (input)은 내부적으로 net 자료형이어야 하고 외부적으로 reg나 net 자료형에 연결된다.
입력 ⇒ net ⇒ reg, net
출력 (output)은 내부적으로 reg나 net 자료형이고 외부적으로 net 자료형에 연결되어야 한다.
출력 ⇒ reg, net ⇒ net
양방향 (inout)은 내부적으로 net 자료형이어야 하고 외부적으로 net 자료형에만 연결되어야 한다.
양방향(inout) ⇒ net ⇒ net
입 출력 신호들의 크기는 같아야한다. 크기가 다르더라도 합성 (synthesis) 툴이 오류를 보고하지 않는다. 포트 신호 위치에 비워두면 연결을 하지 않았다는 의미이다. 구조적 연결을 만들 때 net 자료형이 필요하다. 전가산기의 예에서 s1, c1, 및 c2가 이에 해당된다. 전가산기 예에서 half_adder(ci, a, , s1)나 half_adder(.a(ci), .b(a), .c(), .s(s1))의 의미는 반가산기 의 c에는 아무 것도 연결 안했다라는 의미이다.
테스트벤치 (Test Bench)
설계된 모듈을 테스트하기 위하여 입력 신호들을 가해주어야 할 것이고 출력 신호들을 모니터나 오실로스코프 등을 통하여 살펴보아야 할 것이다. 이러한 것을 Verilog 시물레이션 툴이 지원해 주고 있다. 즉 Verilog 코드로 테스트하는 코드를 만들 수 있다. 이것을 테스트벤치라고 한다. 다음은 full_adder를 테스트하는 테스트벤치 코드이다. 테스트벤치 (test bench) 코드는 입출력을 내부에서 발생하므로 입출력 신호가 필요없다. 테스트하는 모듈명 뒤에 _tb를 붙여 테스트벤치 코드라는 것을 알 수 있도록 하는게 관례이다. 테스트하는 모듈의 입력 신호에 값을 주어야 하기 때문에 모두 reg 자료형으로 선언해야 한다.
module full_adder_tb()
reg ci, a, b;
wire co, s;
full_adder u (ci, a, b, co, s);
initial begin
$monitor(“Time=%t A=%b”, $time, full_adder_tb.u.u0.a);
ci = 0;
a = 0; //ci = 0, b=0, a=0
b = 0;
#5 a = 1; //ci = 0, b=0, a=1
#5 b = 1; //ci = 0, b=1, a=1
#5 a = 1; //ci = 0, b=1, a=0
#5 ci = 1, b = 0; //ci = 1, b=0, a=0
#5 a = 1; //ci = 1, b=0, a=1
#5 b = 1; //ci = 1, b=1, a=1
#5 a = 0; //ci = 1, b=1, a=0
#5 $finish;
end
endmodule
'Study > Verilog' 카테고리의 다른 글
Verilog : UDP (user-defined primitve) (0) | 2017.05.05 |
---|---|
Verilog : 게이트 (0) | 2017.04.28 |
Verilog : 연산자 (3) | 2017.04.28 |
Veriliog : 상수 선언, 모듈, 포트 (1) | 2017.04.28 |
Verilog의 기본 : 숫자표현, 자료형, 벡터, 배열, 문자열 (0) | 2017.04.28 |