[verilog | VHDL]

[VHDL] 4비트 병렬 가감산기(4-bit Full adder / subtractor)

시그널보내 2022. 4. 19. 18:46
4비트 가산기(4-bit Full Adder)

4비트 가산기는 말 그대로 1비트 4개를 더할 수 있는 회로를 의미한다.

회로에서 사용된는 구성요소는 1비트자리 반가산기1개, 전가산기 3개만 적용하면 된다.

처음 LSB연산할때는 하위자리에서 받는 캐리가 없기 때문에 반가산기를 이용하며 나머지 3비트는 전부 캐리를 고려해야 하기 때문에 전가산기를 이용한다. 이러한 동작의 논리회로는 다음과 같다.

최종 결과는 a와b를 더한 결과와 MSB에서 나오는 캐리까지 포함하여 총 5비트가 나오게 된다.

위의 동작을 VHDL 구조적 모델링으로 구현하면 다음과 같다.

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;

entity four_bit_adder_hdl is
	port(
			add_a : in std_logic_vector(3 downto 0);
			add_b : in std_logic_vector(3 downto 0);
			
			add_sum : out std_logic_vector(4 downto 0));
end four_bit_adder_hdl;

architecture sample of four_bit_adder_hdl is
	
	component halfadder_hdl is
		port(
				a : in std_logic;
				b : in std_logic;
				
				sum : out std_logic;
				carry : out std_logic);
	end component;
	
	component fulladder_hdl is
		port(
			fa : in std_logic;
			fb : in std_logic;
			fcin : in std_logic;
			
			fsum : out std_logic;
			fcarry : out std_logic);
	end component;
	
	signal u0_carry : std_logic;
	signal u1_carry : std_logic;
	signal u2_carry : std_logic;
	
begin
	u0 : halfadder_hdl
	port map(
					a => add_a(0),
					b => add_b(0),
					
					sum => add_sum(0),
					carry => u0_carry);
					
	u1 : fulladder_hdl
	port map(
					fa => add_a(1),
					fb => add_b(1),
					fcin => u0_carry,
					
					fsum => add_sum(1),
					fcarry => u1_carry);
					
	u2 : fulladder_hdl
	port map(
					fa => add_a(2),
					fb => add_b(2),
					fcin => u1_carry,
					
					fsum => add_sum(2),
					fcarry => u2_carry);
					
	u3 : fulladder_hdl
	port map(
					fa => add_a(3),
					fb => add_b(3),
					fcin => u2_carry,
					
					fsum => add_sum(3),
					fcarry => add_sum(4));



end sample;

구조적 모델링으로 설계했기 때문에 미리 설계한 컴포넌트 halfadder_hdl, fulladder_hel을 불러온 후 컴포넌트 실체화(port map)를 진행시킨다.

위의 동작을 시뮬레이션 시키면 다음과 같이 가산기 파형을 출력할 수 있다.


4비트 병렬 가감산기

4비트 병렬 가감산기는 4비트의 가산과 감산 동작을 전부 수행할 수 있는 회로이다.

평범한 4비트 가산기와의 차이점은 4비트 전부 전가산기를 이용하며 입력으로 0혹은 1을 xor하여 가산을 할지, 감산을 할지 제어할 수 있다. 이러한 동작의 논리회로는 다음과 같다.

입력M이 0이면 가산기, 1이면 감산기로 동작을 하게 되면 vhdl로 설계하면 다음과 같다.

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;

entity adder_parallel_4bit_VHDL is
	port (
				add_a : in std_logic_vector(3 downto 0);
				add_b : in std_logic_vector(3 downto 0);
				M : in std_logic;
				
				add_sum : out std_logic_vector(4 downto 0)
				);
end adder_parallel_4bit_VHDL;

architecture structural of adder_parallel_4bit_VHDL is

	component fulladder_hdl is
		port(
				fa : in std_logic;
				fb : in std_logic;
				fcin : in std_logic;
				
				fsum : out std_logic;
				fcarry : out std_logic
				);
	end component;
	
	signal u0_carry : std_logic;
	signal u1_carry : std_logic;
	signal u2_carry : std_logic;

begin
	u0 : fulladder_hdl
	port map(
					fa => add_a(0),
					fb => add_b(0) xor M,
					fcin => M,
					
					fsum => add_sum(0),
					fcarry => u0_carry
					);
					
	u1 : fulladder_hdl
	port map(
					fa => add_a(1),
					fb => add_b(1) xor M,
					fcin => u0_carry,
					
					fsum => add_sum(1),
					fcarry => u1_carry
					);	
					
	u2 : fulladder_hdl
	port map(
					fa => add_a(2),
					fb => add_b(2) xor M,
					fcin => u1_carry,
					
					fsum => add_sum(2),
					fcarry => u2_carry
					);	
					
	u3 : fulladder_hdl
	port map(
					fa => add_a(3),
					fb => add_b(3) xor M,
					fcin => u2_carry,
					
					fsum => add_sum(3),
					fcarry => add_sum(4)
					);	


end structural;

해당 코드 역시 구조적 모델링으로 설계하여 fulladder_hdl 컴포넌트만 불러온 후 컴포넌트 실체화를 진행시킨다.

출력파형은 다음과 같다.

M이 0일때 두 값을 더하고, 1이면 두 값을 빼는 동작을 하는것을 알 수 있다.

감산기의 결과값이 해석하기 힘들 수 있는데 예를들어 설명하면 

 

ex1) 큰수에서 작은수 뺄셈(add_a = 1101, add_b = 0100) 1101 + (-0100) -> add_b 2 보수화 -> 1101 + 1100 = 11001 MSB가 1일 때 MSB를 버리면 1001이 되며 두 수의 차를 구할 수 있다.

 

ex2) 작은수에서 큰 수 뺄셈(add_a = 0011, add_b = 1111) 0011 + (-1111) -> 2의 보수화 -> 0011 + 0001 = 00100 언더플로우가 발생했으며 MSB가 0일 때 결과값을 다시 2의 보수화를 시키 면 음수의 형태로 결과를 얻을 수 있다.