Rust로 작성해 보는 컴퓨터 구조 (9) - 반가산기
이 장에서는 반가산기(Half Adder)를 만들것이다. 왜 반가산기라고 하는지는 만들고 나면 알게된다. 아래 게이트 회로가 반가산기의 구조다.
XOR 게이트와 AND 게이트 각 한 개씩으로 구성한 반가산기 회로다. A와 B가 입력이고 S와 C가 출력이다. 이 회로의 진리표를 보자.
입력 A | 입력 B | 출력 C | 출력 S |
---|---|---|---|
0 | 0 | 0 | 0 |
0 | 1 | 0 | 1 |
1 | 0 | 0 | 1 |
1 | 1 | 1 | 0 |
진리표를 보면 입력에 대한 결과가 덧셈임을 알 수 있다. 보기 쉬운 덧셈 기호로 다시 표현해 보면 아래와 같다.
0 + 0 = 00
0 + 1 = 01
1 + 0 = 01
1 + 1 = 10
회로의 동작이 덧셈을 만족하기 때문에 위 회로를 가산기라고 한다. 출력 S에 덧셈 결과가 나오고 출력 C에 자리올림(carry) 결과가 나온다. 그런데 이름에 한 글자가 더 붙어 반가산기라고 한다. 반만 동작하는 가산기라는 뜻이다. 왜 반만 동작하는 것일까? 기능이 반만 있기 때문이다. 나머지 없는 기능 반은 무엇일까? 바로 올림수를 받는 기능이다. 반가산기는 올림수를 출력하긴 하지만 올림수를 받지 않기 때문에 반가산기라고 하는 것이다.
위 게이트 회로를 기반으로 반가산기를 모델링한다. 새로운 파일 adder.rs를 src 폴더에 만들고 아래 코드를 작성한다.
{caption="adder.rs | 가산기 모델 껍데기"} use crate::gates; use gates::GateInterfaces; pub struct HalfAdder { pub conn_a: bool, pub conn_b: bool, pub conn_out_s: bool, pub conn_out_c: bool, xorgate: gates::XorGate, andgate: gates::AndGate, } impl HalfAdder { pub fn new() -> HalfAdder { HalfAdder { conn_a: false, conn_b: false, conn_out_s: false, conn_out_c: false, xorgate: gates::XorGate::new(), andgate: gates::AndGate::new(), } } } pub trait AdderInterfaces { fn proc(&mut self, input_a: bool, input_b: bool); } impl AdderInterfaces for HalfAdder { fn proc(&mut self, input_a: bool, input_b: bool) { } }
반가산기 모델 본체인 proc() 함수는 아직 만들지 않았다. 일단 껍데기만 미리 만들어 놓고 유닛 테스트를 만들기 위함이다. 그래서 위 코드는 반가산기 모델의 틀만 잡아 놓은 코드다. 5번째 줄에서 13번째 줄이 반가산기에 대한 구조체인 HalfAdder 구조체 선언이다. 입력 A, B 두 개와 출력 S, C 두 개를 선언하고 XOR 게이트와 AND 게이트 모델 변수를 선언했다. 15번째 줄에서 27번째 줄이 HalfAdder 객체의 생성자다. 신호선은 모두 false로 초기화하고 XOR 게이트와 AND 게이트 객체를 할당했다. 29번째 줄부터 31번째 줄이 트래잇 선언이다. 가산기의 proc() 인터페이스는 리턴값이 없다. 출력 신호가 두 개기 때문이다. 그래서 proc() 함수의 리턴은 없고 결과를 보려면 proc() 함수를 호출한 후에 conn_out_s와 conn_out_c의 값을 읽어야 한다. 35번째 줄 위치에 반가산기 모델 코드가 들어가야 한다. 일단 지금은 비워두고 유닛 테스트를 먼저 만든다.
유닛 테스트는 tests 폴더에 만든다. tests 폴더에 adder_test.rs 파일을 만들고 아래 코드를 작성한다.
{caption="adder_test.rs | 반가산기 유닛 테스트"} extern crate programming_coms; use programming_coms::adder; use adder::AdderInterfaces; #[test] fn test_halfadder() { let mut half_adder = adder::HalfAdder::new(); half_adder.proc(false, false); assert_eq!(false, half_adder.conn_out_c); assert_eq!(false, half_adder.conn_out_s); half_adder.proc(false, true); assert_eq!(false, half_adder.conn_out_c); assert_eq!(true, half_adder.conn_out_s); half_adder.proc(true, false); assert_eq!(false, half_adder.conn_out_c); assert_eq!(true, half_adder.conn_out_s); half_adder.proc(true, true); assert_eq!(true, half_adder.conn_out_c); assert_eq!(false, half_adder.conn_out_s); }
위 코드는 반가산기의 진리표를 HalfAdder 객체가 만족하는지 확인하는 유닛 테스트다. 11번째 줄에 half_adder.proc() 메소드를 호출했다. 그러면 반가산기 모델이 동작한다. 동작 결과는 12, 13번째 줄에 나온대로 half_adder.conn_out_c와 half_adder.conn_out_s를 읽어서 확인한다. 같은 패턴으로 11번째 줄에서 25번째 줄까지 코드에 반가산기 진리표를 확인하는 테스트를 작성한다.
현 상태에서 유닛 테스트를 실행하면 당연히 실패한다. 먼저 테스트를 만들어서 실패하는 것을 보고 코드를 수정해서 테스트를 성공시키는 순서로 작업한다.
$ cargo test
... 생략 ...
running 1 test
test test_halfadder ... FAILED
failures:
---- test_halfadder stdout ----
thread 'test_halfadder' panicked at 'assertion failed:(left == right)
left:true
,
right:false
', tests/adder_test.rs:17:5
테스트가 실패했다고 나온다. 이제 다시 adder.rs에서 작업한다.
{caption="adder.rs | 반가산기 모델 본체"} // ... 생략 ... impl AdderInterfaces for HalfAdder { fn proc(&mut self, input_a: bool, input_b: bool) { self.conn_a = input_a; self.conn_b = input_b; self.conn_out_s = self.xorgate.proc(input_a, input_b); self.conn_out_c = self.andgate.proc(input_a, input_b); } }
반가산기 게이트 회로를 보면 입력 A, B가 각각 XOR 게이트와 AND 게이트에 독립적으로 들어간다. XOR 게이트 출력이 그대로 출력 S고 AND 게이트 출력이 그대로 출력 C다. 그 구성 그대로 모델링한 코드가 위 코드다.
이렇게 작업하고 유닛 테스트를 실행한다. 유닛 테스트가 통과한다면 반가산기 모델을 제대로 만든 것이다.
$ cargo test
... 생략 ...
running 1 test
test test_halfadder ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
running 7 tests
test test_and_gate ... ok
test test_inverter ... ok
test test_nand_gate ... ok
test test_nor_gate ... ok
test test_or_gate ... ok
test test_transistor ... ok
test test_xor_gate ... ok
test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
앞 장에서 만든 게이트 유닛 테스트와 방금 만든 반가산기 유닛 테스트가 모두 통과했다. 따라서 반가산기 모델이 잘 동작함을 확인했다.
첨부 | 파일 크기 |
---|---|
adder-gate-construction.png | 15.95 KB |
댓글
그림에서 XOR 게이트는 식별 가능할테고 아래에 있는
그림에서 XOR 게이트는 식별 가능할테고 아래에 있는 게이트는 조금 이상하게 생기긴 해도 AND 게이트입니다.
----------------------
얇은 사 하이얀 고깔은 고이 접어서 나빌레라
댓글 달기