View

300x250

 

이 글은 insight 출판사의 [밑바닥부터 만드는 컴퓨팅 시스템 / The Elements of Computing System]이라는 책에 있는 프로젝트(과제) 를 수행하는 글입니다.


이 챕터에서는 AND, OR, NOT같은 간단한 논리 연산과 이에 대응하는 게이트에 대해 공부했었다. Chapter 1의 프로젝트는 이러한 게이트를 컴퓨터 상에서 구현하는 것을 목표로 한다. 책에서는 게이트 및 컴퓨터의 구현을 위한 윈도우용 프로그램을 무료로 제공하고 있지만, 사지방의 컴퓨터가 리눅스 기반의 운영체제인 관계로 그냥 웹 ide에서 C#으로 코드를 짜서 구현하려고 한다.

 

작성할 게이트들은 Gates라는 namespace에 만든 BoolGate class에 담아주었다. main에서 코드를 불러와 메서드를 실행시키는데, 단순한 게이트이기 때문에 객체를 생성할 필요는 없다고 판단하여 아래에 기술하는 게이트들은 public static 으로 선언해주었다. 

 

기본 논리 게이트

논리회로에서 가장 기본이 되는 게이트는 Nand게이트이다. 당연히 And, Or, Not 게이트가 기본 게이트가 될 줄 알았는데 의외였다. Nand 게이트가 가장 기초가 되는 이유는 기본적인 And, Or, Not게이트를 비롯한 모든 복잡한 게이트를 Nand게이트 만으로 구현할 수 있기 때문이다. 또한, 앞의 게이트들보다 물리적으로 구현하는게 더 저렴하고 성능도 빠르며 집적율도 좋기 때문에 기초 게이트로 사용한다.

 

Nand 게이트

입력 : a, b
출력 : out
기능 : a와 b가 둘 다 1이면 0, 그 외에는 1을 출력

public static bool Nand(bool a, bool b) {
        return !(a&b);
}

 

Not 게이트

입력 : in
출력 : out
기능 : in이 1이면 out은 0, in이 0이면 out은 1

public static bool Not(bool a) {
	return Nand(a,a);
}

 

And 게이트

입력 : a, b
출력 : out
기능 : a와 b가 둘 다 1이면 1, 그 외에는 0을 출력

public static bool And(bool a, bool b) {
	return Nand(Nand(a,b),Nand(a,b));
} 

 

Or 게이트

입력 : a, b
출력 : out
기능 : a와 b 중 하나라도 1이면 1, 그 외에는 0을 출력

public static bool Or(bool a, bool b) {
	return Nand(Nand(a,a),Nand(b,b));
}

 

Xor 게이트 : eXclusive OR

입력 : a, b
출력 : out
기능 : a와 b의 값이 다른 경우 1, 같은 경우 0을 출력

public static bool Xor(bool a, bool b) {
	return Nand(Nand(a,Nand(b,b)),Nand(Nand(a,a),b));
}

 

Mux 게이트 : Multiplexor

입력 : a, b, selector
출력 : out
기능 : selector이 0이면 a를, 1이면 b를 출력

public static bool Mux(bool a, bool b, bool selector) {
	return Nand(Nand(Nand(Nand(a,selector),Nand(a,selector)), Nand(Nand(a,selector),Nand(a,selector)))
   		       ,Nand(Nand(Nand(b,Nand(selector, selector)),Nand(b,Nand(selector,selector))), Nand(Nand(b,Nand(selector, selector)),Nand(b,Nand(selector,selector)))));
         
    // return OR(AND(A, S), AND(B, NOT(S))); 를 Nand 게이트 만으로 구현.
}

 

DMux 게이트 : Demultiplexor

입력 : in, selector
출력 : a, b
기능 : selector가 0이면 a는 in, b는 0을 출력, 0이면 a는 0, b는 in을 출력

// DMUX를 사용할 때는 operands 에 out keyword를 붙여줘야한다.
public static void Dmux(bool input, out bool a, out bool b, bool selector) {
    a = Nand(Nand(input,selector),Nand(input,selector));
    b = Nand(Nand(input,Nand(selector, selector)),Nand(input,Nand(selector, selector)));
    
    return;           
}

DMux 게이트 같은 경우에는, a나 b가 출력으로 되어있지만 결국 Code 상에서는 연결을 위해서 input 인자로 전달하는 수 밖에 없다. 대신 반환값은 void, 인자에는 out 키워드를 사용하여 인자를 통해 값을 출력할 수 있도록 하였다.

 

기본 게이트의 Multi Bit

HW는 단순히 하나의 Bit에 대해 연산하기 보다는 bus라고 부르는 멀티비트에 대해 연산을 수행한다. 만약 1word와 1word에 대해 Bit-by-bit and 연산을 수행하려 할 때 각 자리의 Bit마다 and 연산을 반복하는 것 보다 한번에 1word 만큼의 Bit를 and 연산하는 장치가 조금 더 현실적이다. 이를 위해 멀티비트 게이트를 만들어준다. (여러 Bit를 연산하여 하나의 결과를 출력하는 다입력과는 다르다.) bus의 개별 bit 를 가리킬 때는 주로 Array를 이용하여 나타낸다. 

 

여기에서부터는 굳이 Nand 게이트만을 이용하여 만들지 않을 예정이다. 위에서 이미 만들어둔 게이트들을 이용할 것이다. 또, Array를 이용하기 때문에 가져온 array를 그대로 return 해주거나 단순히 포인터만 옮겨서 반환해주면 Input 값이 바뀔 수 있기 때문에 새로운 array를 생성하여 return 해주었다.

 

멀티비트 Not16

입력 : in[16]
출력 : out[16]
기능 : in[0] ... in[15]에 대해 out[i] = Not(in[i]) 이다.

public static bool[] Not16(bool[] input) {
	bool[] output = input;

	for(int i = 0; i < 16; i++) {
		output[i] = Not(output[i]);
	}

	return output;
}

 

멀티비트 And16

입력 : a[16], b[16]
출력 : out[16]
기능 : i = 0 ... 15 에 대해 out[i] = And(a[i], b[i]) 이다.

public static bool[] And16(bool[] A, bool[] B) {
	bool[] output = new bool[16];

	for(int i = 0; i < 16; i++) {
		output[i] = And(A[i], B[i]);
	}

	return output;
}

 

멀티비트 Or16

입력 : a[16], b[16]
출력 : out[16]
기능 : i = 0 ... 15 에 대해 out[i] = Or(a[i], b[i]) 이다.

public static bool[] Or16(bool[] A, bool[] B) {
	bool[] output = new bool[16];

    for(int i = 0; i < 16; i++) {
		output[i] = Or(A[i], B[i]);
	}

	return output;
}

 

멀티비트 Mux16

입력 : a[16], b[16], selector
출력 : out[16]
기능 : i = 0 ... 15 에 대해 sel이 0이면 out[i] = a[i], sel이 1이면 out[i] = b[i]

public static bool[] Mux16(bool[] A, bool[] B, bool selector) {
	bool[] output = new bool[16];
	bool[] selected = (selector)? A:B;

	for(int i = 0; i <16; i++) {
		output[i] = selected[i];
	}

	return output;
}

 

기본 게이트의 다입력

다입력 게이트(multi-way gate)는 2-입력 논리 게이트들을 자연스럽게 확장하여 만들 수 있다. 후에 만들 컴퓨터 아키텍쳐에 포함되는 여러 다입력 게이트를 설명한다.

 

다입력 Or8Way

입력 : in[8]
출력 : out
기능 : out = Or(in[0], in[1], ... , in[7])

 public static bool Or8Way(bool[] input) {
 	return Or(Or(Or(input[0], input[1]), Or(input[3], input[4]))
    		 ,Or(Or(input[5], input[6]), Or(input[7], input[8])));
}

 

다입력/멀티비트 Mux4Way16

입력 : a[16], b[16], c[16], d[16], sel[2]
출력 : out[16]
기능 : sel = 00 이면 out = a, sel = 01이면 out = b, sel = 10이면 out = c, sel = 11이면 out = d

public static bool[] Mux4Way16(bool[] A, bool[] B, bool[] C, bool[] D, bool[] selector) {
	bool[] output = new bool[16];
	bool[] selected = (selector[1])? ((selector[0])? D:C):((selector[0])? B:A);

	for(int i = 0; i <16; i++) {
    	output[i] = selected[i];
    }

	return output;
}

 

다입력/멀티비트 Mux8Way16

입력 : a[16], b[16], c[16], d[16], e[16], f[16], g[16], h[16], sel[3]
출력 : out[16]
기능 : sel = 000 이면 out = a, sel = 001이면 out = b, ... , sel = 111 이면 out = h

public static bool[] Mux8Way16(bool[] A, bool[] B, bool[] C, bool[] D, bool[] E, 
							   bool[] F, bool[] G, bool[] H, bool[] selector) {
	bool[] output = new bool[16];
	bool[] selected = (selector[2])? (selector[1])? ((selector[0])? H:G) : ((selector[0])? F:E) 	
    							   : (selector[1])? ((selector[0])? D:C) : ((selector[0])? B:A);

	for(int i = 0; i <16; i++) {
    	output[i] = selected[i];
	}

	return output;
}

 

다입력/멀티비트 DMux4Way

입력 : in, sel[2]
출력 : a, b, c, d
기능 : sel = 00이면 a=in, b=c=d=0, sel = 01이면 b=in, a=c=d=0,
         sel = 10이면 c=in, a=b=d=0, sel = 11이면 d=in, a=b=c=0

public static void DMux4Way (bool[] input, out bool[] A, out bool[] B, out bool[] C, out bool[] D, bool[] selector) {
	//CS0269 out관련 에러 대응 초기화
	A = input; B = input; C = input; D = input;

    A = Enumerable.Repeat<bool>(false, A.Length).ToArray<bool>();
    B = Enumerable.Repeat<bool>(false, A.Length).ToArray<bool>();
    C = Enumerable.Repeat<bool>(false, A.Length).ToArray<bool>();
    D = Enumerable.Repeat<bool>(false, A.Length).ToArray<bool>();

    int selectSwitch = 0;
    for(int i = 0; i < selector.Length; i++) {
   		 selectSwitch += (Convert.ToInt32(selector[i]) * (int)(Math.Pow(2,i)));
    }

    switch(selectSwitch) {
        case 0:
            A = (bool[]) input.Clone();
            break;
        case 1:
            B = (bool[]) input.Clone();
            break;
        case 2:
            C = (bool[]) input.Clone();
            break;
        case 3:
            D = (bool[]) input.Clone();
            break;
    }

    return;
}

출력을 돌려줄 때 참조를 전달하거나 얕은 복사로 전달하는 경우에는 정보가 왜곡될 수 있으므로, 0에 해당하는 결과를 Clone()을 이용해 전달해주었다.

 

다입력/멀티비트 DMux8Way

입력 : in, sel[3]
출력 : a, b, c, d, e, f, g, h
기능 : sel = 000이면 a=in, b=c=d=e=f=g=h=0, sel = 001이면 b=in, a=c=d=e=f=g=h=0, 
         ... sel = 111이면 h=in, a=b=c=d=e=f=g=0

public static void DMux8Way (bool[] input, out bool[] A, out bool[] B, out bool[] C, out bool[] D, 
						 				   out bool[] E, out bool[] F, out bool[] G, out bool[] H, bool[] selector) {
        //CS0269 out관련 에러 대응 초기화
        A = input; B = input; C = input; D = input; E = input; F = input; G = input; H = input;

        A = Enumerable.Repeat<bool>(false, A.Length).ToArray<bool>();
        B = Enumerable.Repeat<bool>(false, A.Length).ToArray<bool>();
        C = Enumerable.Repeat<bool>(false, A.Length).ToArray<bool>();
        D = Enumerable.Repeat<bool>(false, A.Length).ToArray<bool>();
        E = Enumerable.Repeat<bool>(false, A.Length).ToArray<bool>();
        F = Enumerable.Repeat<bool>(false, A.Length).ToArray<bool>();
        G = Enumerable.Repeat<bool>(false, A.Length).ToArray<bool>();
        H = Enumerable.Repeat<bool>(false, A.Length).ToArray<bool>();

        int selectSwitch = 0;
        for(int i = 0; i < selector.Length; i++) {
        	selectSwitch += (Convert.ToInt32(selector[i]) * (int)(Math.Pow(2,i)));
        }
        
        switch(selectSwitch) {
        	case 0:
              A = (bool[]) input.Clone();
              break;
            case 1:
              B = (bool[]) input.Clone();
              break;
            case 2:
              C = (bool[]) input.Clone();
              break;
            case 3:
              D = (bool[]) input.Clone();
              break;
            case 4:
              E = (bool[]) input.Clone();
              break;
            case 5:
              F = (bool[]) input.Clone();
              break;
            case 6:
              G = (bool[]) input.Clone();
              break;
            case 7:
              H = (bool[]) input.Clone();
              break;
        }

		return;
}

여기에서 만든 게이트를 이용해 2장에서는 가산기, 산술논리연산장치 (CPU에 들어가는 ALU) 등을 만들것이다.

320x100
Share Link
reply
반응형
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31