1. 조합회로란?
조합회로는 입력 신호를 처리하여 출력 신호를 즉시 생성한다. 동기 방식(클럭을 사용하는 방식)인 순차회로와는 달리, 이러한 회로는 입력값에만 의존하며, 출력은 항상 동일한 입력에 대해 일관된 결과를 제공한다. 따라서 조합회로는 논리 게이트로 구성되며, 논리 연산자의 출력은 현재 입력에만 의존한다.
module gate4a(
input a, b, c, d,
output y_a, y_b
);
wire and_ab, and_cd, or_bc;
assign and_ab = a & b;
assign and_cd = c & d;
assign or_bc = b | c;
assign y_a = (and_ab | and_cd);
assign y_b = (a & d) & or_bc;
endmodule
위 코드는 네 개의 입력 신호 a, b, c, d를 받아 두 개의 출력 신호 y_a, y_b를 생성하는 조합논리회로 모듈을 Verilog로 작성한 것이다.
각각의 출력 신호는 입력 신호에 따라 다음과 같이 동작한다.
y_a : 입력 a와 b를 AND 연산하고, 입력 c와 d를 AND 연산한 결과를 OR 연산하여 생성
y_b : 입력 a와 d를 AND 연산하고, 입력 b와 c를 OR 연산한 결과에 AND 연산하여 생성
이를 구현하기 위해, 입력 신호 간의 AND, OR 연산을 위한 wire 변수를 정의하고, assign 문을 이용하여 출력 신호와 wire 변수들 간의 연결을 구현하였다.
구체적으로, and_ab, and_cd, or_bc라는 wire 변수를 선언하였고, 각각 입력 a와 b, c와 d, b와 c에 대한 AND, OR 연산 결과를 계산하여 할당하였다.
그리고 나서, y_a와 y_b에 대한 출력 신호를 assign 문을 이용하여 다음과 같이 계산하였다.
y_a : and_ab와 and_cd의 OR 연산 결과를 할당
y_b : a와 d의 AND 연산 결과와 or_bc의 AND 연산 결과를 할당
결과적으로, 위의 모듈은 주어진 네 개의 입력에 대하여 정의된 논리식에 따라 두 개의 출력을 생성하게 된다.
자일링스의 RTL analysis를 통해서 위 코드의 회로를 확인할 수 있다. 각 게이트에서 and와 or연산을 후 y_a와 y_b의 연산을 거쳐 결과가 출력됨을 알 수 있다.
2. 조합회로를 이용한 반가산기
두 개의 1비트 숫자를 더하는 데 사용되는 가장 간단한 논리 회로인 반가산기를 만들어보자.
반가산기는 입력 두 개와 출력 두 개로 구성되며, 각각 입력 A, B와 출력 합(S)과 자리올림(C)으로 불린다. 반가산기는 두 개의 입력 비트를 더하고 자리올림을 계산하지 못하는 특징이 있다.
`timescale 1ns / 1ps
// Module Name: half_adder
//////////////////////////////////////////////////////////////////////////////////
module half_adder(
input A,
input B,
output S,
output C
);
xor u1 (S, A, B);
and u2 (C, A, B);
endmodule
게이트 레벨 모델링으로 코드를 구현해보았다. 아래는 시뮬레이션이고 결과가 출력이 잘 됨을 알 수 있다.
RTL Analysis를 이용한 회로도이다. 이상적인 반가산기 디지털 회로를 볼 수 있다.
3. 반가산기 2개를 이용한 전가산기 만들기
앞서 만들었던 반가산기 2개를 이용하여 전가산기를 만들어보자.
게이트 레벨 모델링에서는 내장된 모듈은 인스턴스명을 주지 않고 불러올 수 있었다. 하지만 우리가 방금 직접 만든 모듈 half_adder을 불러올 때, 인스턴스명을 아래와 같이 붙여주어야 한다.
`timescale 1ns / 1ps
// Module Name: fadder
module fadder(
input A,
input B,
input Cin,
output S,
output Cout
);
wire s0, co0, co1;
half_adder ha0(.A(A), .B(B), .S(s0), .C(co0));
half_adder ha1(.A(s0), .B(Cin), .S(S), .C(co1));
or u0 (Cout, co0, co1);
endmodule
직접 만든 모듈을 사용할 경우, 모듈 이름 뒤에 인스턴스 명을 붙여주고, .Input(output)의 모양으로 써주어야 한다. 또한 wire의 경우, 게이트 사이에 연결되는 신호선을 따로 선언을 해야하기 때문에 wire로 s0, co0, co1을 선언하였다.
반가산기 ha0, ha1을 두개의 모듈을 합쳐 위와 같이 전가산기를 완성하였다.
아래는 전가산기 타이밍 시뮬레이션이다.
4. 4비트 전가산기 만들기
이전까지는 1비트 전가산기를 만들어 보았다. 이번에는 input과 output의 크기를 늘려 4비트짜리 전가산기를 만들어보자.
또한 4개의 전가산기가 필요하므로 방금 만들었던 fadder을 이용한다.
`timescale 1ns / 1ps
// Module Name: fadder_4bit
module fadder_4bit(
input [3:0] A,
input [3:0] B,
input Cin,
output [3:0] S,
output Cout
);
wire c1, c2, c3;
fadder fa0(.A(A[0]), .B(B[0]), .Cin(Cin), .S(S[0]), .Cout(c1));
fadder fa1(.A(A[1]), .B(B[1]), .Cin(c1), .S(S[1]), .Cout(c2));
fadder fa2(.A(A[2]), .B(B[2]), .Cin(c2), .S(S[2]), .Cout(c3));
fadder fa3(.A(A[3]), .B(B[3]), .Cin(c3), .S(S[3]), .Cout(Cout));
endmodule
입력 A,B와 출력 S의 비트 수를 4비트로 늘렸으므로, 10진수로 출력은 16진수까지 될 것이다, 또한 16을 넘을 경우 Carry Out이 발생하여 Cout값이 1이 될 것이다. 또한 중앙의 신호선 역할을 할 c1, c2, c3를 wire 자료형으로 선언하였고, 방금 만들었던 fadder을 사용하여 게이트를 연결 시켜주었다.
'FPGA' 카테고리의 다른 글
[FPGA] 6. Basys3 두 개로 Encoder <--> Decoder 구현 / 7-SEG Decoder 구현 (0) | 2023.04.18 |
---|---|
[FPGA] 5. Basys3 사용해보기 (0) | 2023.04.18 |
[FPGA] 4. 대표적인 모델링 방법 (Data Flow/Gate Level/Behavioral Modeling) (0) | 2023.04.18 |
[FPGA] 3. Verilog의 순차 회로 (0) | 2023.04.18 |
[FPGA] 1. Verilog 기본과 문법(4/17) (0) | 2023.04.17 |