메모리와 디스크의 핵심 : 순차 논리
개요
이전 장에서는 조합 논리는 입력에 의해서만 출력이 결정된다는 내용을 배웠지만,
조합 논리만으로는 흐름의 일부만을 떼어내 기억할 수는 없다.
순차 논리는 입력의 현재 상태와 과거 상태를 함께 고려해 이러한 문제를 해결할 수 있다.
시간 표현과 상태 기억
지구의 자건 같은 외부 이벤트를 활용한 주기 함수로 시간을 측정할 수 있고,
마찬가지로 진자가 오가는 주기 같은 것을 사용해 시계를 만든다거나 할 수 있다.
컴퓨터도 마찬가지로 전자공학을 사용하기 때문에 주기적인 전기 신호가 필요하다.
발진자
feedback(되먹임)
인버터의 출력을 입력에 연결해 입력 → 출력 → 입력 순환이 가능해져
주기적이고 반복적인 진동 신호를 생성할 수 있고, 이를 진동한다고 볼 수 있다.
이 과정에서 진동하는 속도는 전파 지연과 온도에 따라 달라지는데,
더 안정적이고 정확한 발진자를 적은 비용으로 효율적으로 만드려면 크리스탈을 활용한다.
크리스탈
전극을 크리스탈에 연결하고 크리스탈을 압축하면 크리스탈이 전기를 만들고,
전극에 전기를 가하면 크리스탈이 구부러지는 피에조 전기(압전) 효과가 발생한다.
이 압전 효과를 사용해 음성 진동을 잡아 마이크를 만들 수도 있고,
반대로 전기를 가해 음성 진동을 만들어 다양한 경보음을 낼 수도 있다.
크리스탈 발진자는 단극쌍투 스위치를 사용해 전기를 가해 다시 전기를 만드는데
전기로 부터 전기를 다시 만드는 시간은 예측이 가능하고 많이 정확하다.
크리스탈 중에서도 quartz(석영)는 아주 좋고 싼 크리스탈이라 많이 사용되었다.
클럭
발진자는 컴퓨터에 시간을 셀 수 있게 해주는 클럭이라는 신호를 제공하고,
클럭은 회로의 페이스를 결정하고, 회로의 최대 클럭 속도나 가장 빠른 템포는
회로의 전파 지연 시간에 의해 결정된다.
Binning
부품을 측정해서 특성에 따라 여러 다른 빈이나 무더기로 분류하는 과정으로
지연 시간이 짧아 반응이 빠른 부품은 가장 비싼 빈에 들어가는 식으로
이러한 분류 단계를 거쳐 더 작은 편차를 갖도록 부품을 빈에 나눠 담는다.
그래서 부품의 전파 지연 시간을 표시할 때도 범위를 표시하고 있는데
바로 전형적인 값, 최솟값, 최댁값이다.
일반적인 논리 회로 설계 오류는 최댓값이나 최솟값을 사용하지 않고
전형적인 값을 사용해서 생기는데, 이는 설계자가 최악과 최선의 경우를
생각하지 않고 회로의 성능을 평가하거나 설계해서다.
오버클로킹
통계적으로 중간 정도에 위치하는 부품을 부품이 고장 나지 않을 범위 내에서
클록을 빠르게 공급하도록 수정한다는 말이다.
래치
래치는 출력을 입력에 묶는 피드백을 사용해 정보를 기억할 수 있다.
OR 게이트 래치
피드백을 통해 한 번 설정된 출력의 상태를 그대로 유지하기 때문에
이후에 입력이 바뀌어도 출력이 바뀌지 않는다.
AND-OR 게이트 래치
피드백을 끊고 회로를 리셋할 수 있고 두 게이트의 역할은 다음과 같다.
AND 게이트는 OR 게이트의 출력과 RESET(제어 신호)을 입력으로 받아 래치의 상태를 관리한다.
RESET은 OR 게이트의 피드백 경로를 차단해 상태를 로우로 리셋할 수 있다.
OR 게이트는 입력 중 하나가 하이면 하이를 출력하는데, 초기 상태에서 입력이 로우면 출력도 로우지만
입력이 하이로 전환되면 출력이 하이로 계속 유지된다.
S(Set)-R(Reset) 래치
좀 더 효율적으로 1비트 메모리를 만드는 방법으로 액티브 로우 입력을 받아 보수 출력을 제공한다.
보수 출력은 한쪽은 액티브 하이, 반대쪽은 액티브 로우라는 뜻이다.
S-R이 모두 참인 경우는 두 출력이 모두 참이라 이런 입력은 사용하면 안되고,
두 입력이 모두 하이로 바뀌는 경우에도 전파 지연 시간에 따라 출력이 달라져 결과를 예측할 수 없다.
AND-OR 게이트 래치와 비교했을 때 설계가 대칭적이라 S-R 신호의 지연 시간이 비슷하다는 장점이 있다.
게이트가 있는 래치
기존 S-R 래치는 S-R 입력을 무시할 수 있는 방법이 없지만 OR 게이트를 추가해 S-R 래치를 ON/OFF 할 수 있다.
즉 Gate S-R 래치에서는 게이트바가 하이면 입력으로 어떤 값이 들어와도 출력이 변하지 않고, 로우일 때만 변한다는 말이다.
Gate-D 래치에서는 S-R 두 개의 입력 대신 D 입력 하나로 묶어서 처리할 수 있다. 한쪽의 입력에 인버터를 추가해
기존 S-R 입력에 서로 보수 관계의 입력만 가능하기 때문에 입력 간소화가 가능하고 금지 입력을 막을 수 있다.
다만 이 래치는 게이트바가 참인 경우 입력이 변하면 그 변화가 바로 출력에 반영되는 문제가 있다.
즉, 게이트바가 활성화 된 동안 입력이 빠르게 들어오면 예상치 못한 출력 변화가 발생한다는 것이고,
게이트바의 신호만으로 동작하기 때문에 동기화가 보장되지 않는다.
플립플롭
이러한 문제를 최소화하기 위해 등장한 방법으로 edge에 의해 변화가 촉발되는 래치다.
Edge
논리 수준이 한 수준에서 다른 수준으로 전이되는 것
= 클럭 신호가 변화하는 순간
플립플롭은 래치를 기본 요소로 사용해서 만들어지고, 3개의 S-R 래치를 연결해
음 혹은 양의 edge에 의해 변화가 트리거되는 D 플립플롭을 만들 수 있다.
즉, edge에 의해 변화가 트리거 된다는 말은 논리 수준이 1에서 0 혹은 0에서 1로 바뀌는 순간에 플립플롭의 출력이 바뀐다는 뜻으로 이해하면 된다.
D 플립플롭에서는 클록이 로우면 D 입력이 아무리 들어와도 입력을 무시해 이전 상태를 그대로 유지하고
클록이 하이면 활성화되어 바뀐 순간의 D 입력의 값이 복사되어 출력에 저장되고 이 값은 클록이 0으로 돌아갈 때까지 유지된다.
카운터
플립플롭을 응용한 회로 중 1, 2, 3 순서대로 수를 세는 카운터가 있다.
리플 카운터
개수를 센 결과가 왼쪽에서 오른쪽으로 퍼져나가는 방식으로
C0이 C1을 바꾸고, C1이 C2을 바꾸는 식으로 과정을 반복해 퍼져나가고
각 비트의 상태가 다른 비트의 상태 변화에 약간의 시차를 두고 바뀌기 때문에 비동기 카운터라고 부른다.
비동기적 카운터는 언제 결과를 봐야 맞는지 알기 어렵고, 전파되는 동안의 출력은 올바르지 않다.
그래서 전파 지연을 감안해 수를 세면 괜찮지만 그렇지 않고 전파 지연을 감안하지 않고 빠른 속도로
입력을 변화시키면 출력이 틀리는 경우가 생긴다.
동기적 카운터
이러한 리플 카운터의 타이밍 문제는 동기적 카운터를 통해서 해결할 수 있는데,
동기적 카운터는 상태 변경이 동시에 일어나고, 이는 모든 플립플롭에서 같은 클록을 병렬로 연결한단거다.
즉, 모든 플립플롭에 같은 클록이 들어가, 카운터의 모든 플립플롭의 상태가 동시에 변하기에
기존에 플립플롭을 연속적으로 연결해서 생기는 타이밍 문제를 해결할 수 있다.
레지스터
클록을 공유하는 D 플립플롭 여러 개를 한 패키지에 넣은 것을 레지스터라고 한다.
중간 정리
발진자
반복적이고 주기적인 신호인 클럭을 생성
클럭
컴퓨터에서 연산 타이밍을 조정하는 신호
래치
1비트를 임시로 저장할 수 있는 기억소자
플립플롭
클럭 신호의 edge에 따라 동작하는 기억소자
레지스터
CPU 내부에 있는 작은 임시 저장 장치로 빠르다.
흐름
발진자 → 클럭 → 래치/플립플롭 → 레지스터
메모리 조직과 주소 지정
더 많은 비트를 저장해야 한다면 가장 간단하게 더 많은 레지스터를 쌓아두는 것을 생각할 수 있다.
하지만 이러면 어떤 레지스터를 사용해야 하는지를 지정해줘야 하는데, 이는 디코더를 사용해
입력된 주소를 기반으로 일치하는 특정 레지스터를 선택하는 것으로 해결할 수 있다.
입력할 레지스터를 선택했으면 레지스터의 출력을 선택할 방법도 필요한데
이는 다수의 입력 중 하나를 선택해 출력으로 전달하는 실렉터를 사용해
특정 레지스터의 출력을 선택해 전달하는 것으로 해결할 수 있다.
(만약 여러 메모리 컴포넌트의 출력을 한 출력으로 연결해야 하면 트라이스테이트 출력이 추가로 필요하다.)
메모리 컴포넌트는 비트 수만큼 입/출력을 연결해야 해서 연결 지점이 굉장히 많기 때문에 이를 줄이려했다.
- 메모리를 동시에 읽고 쓸 필요가 거의 없으니 연결을 줄인다.
- 입력과 출력 데이터 연결을 합치고 read/write-bar 제어 신호를 사용해 연결을 줄인다.
추가로 메모리 크기가 늘어나면 주소로 연결해야 할 비트 수도 많아진다는 문제가 있는데
원인은 메모리가 각 바이트마다 고유한 주소를 갖기 때문이고, 멀티플렉싱을 통해 해결할 수 있다.
주소가 한 번에 행과 열 두 부분으로 나누어 들어오기 때문에, 행 주소를 먼저 전송하고, 열 주소를 전송하기 때문에
기존에 8비트를 연결할 때는 8비트의 행과 열 주소를 합친 16개가 필요했다면, 이 방식을 사용하면 절반인 8개만 필요하다.
임의 접근 메모리
이러한 메모리를 RAM(Random Access Memory)라고 부르고,
이를 사용해 메모리의 원하는 곳이 어디든 원하는 순서로 읽고 쓰기가 가능하다.
SRAM
- 비싸지만 아주 빠르다.
- 각 비트에 트랜지스터가 6개 들어가 공간을 많이 차지해 많은 비트를 저장하기엔 부적합하다.
DRAM
- Capacitor라는 작읍 버킷에 전자를 담고, 트랜지스터를 하나만 사용해 뚜겅을 덮는다.
- 버킷에 누수 현상이 있어 종종 메모리를 갱신해줘야 한다.
- 갱신 = 버킷에 전자를 다시 채워줘야 한다.
- 버킷에 전자를 채우는 시점과 정보를 쓰는 시간이 겹치지 않게 조심해야 한다.
- 빛이 버킷에 비치면 누수 속도가 빨라진다.
- 단위 면적당 비트 수가 높아 큰 메모리 칩에 적합하다.
SRAM과 DRAM 모두 전원이 끊어지면 데이터가 사라지는 휘발성 메모리지만
코어 메모리는 비휘발성 RAM으로 비트를 토러스 모양 쇳조각에 저장한다.
읽기 전용 메모리
ROM(Read Only Memory)은 한 번만 쓸 수 있고, 여러 번 읽을 수 있는 메모리다.
전자레인지와 같은 프로그램을 내장해야 하는 장치에서 유용하게 사용할 수 있다.
블록 장치
디스크 드라이브는 대용량 데이터를 저장할 때 사용하는 장치로
자화된 플래터에 비트를 저장하고 디스크가 돌면 디스크 헤드가 정보를 가져온다.
하지만 방금 지나간 데이터를 다시 읽으려면 디스크가 다시 한 바퀴 돌아야
디스크 헤드가 읽을 수 있는 구조다 보니 느리고
물리적으로 회전하면서 데이터를 읽다보니 사용할 수록 낡아져 오류가 발생하기도 한다.
디스크 영역을 자화시켜서 데이터를 저장하기 때문에 비휘봘성 기억 장치고,
기록 밀도와 속도를 맞바꾼 장치지만 주소나 데이터 연결을 위한 별도의 공간이 필요 없다.
디스크는 블록 단위로 주소를 지정해 읽고, 블록을 섹터라고 부르며, 읽고 쓰기가 가능한 최소 단위다.
디스크는 한 바이트만 바꾸려해도 전체 블록을 읽고 원하는 바이트를 바꾸고 전체 블록을 다시 써야한다.
모든 섹터에 같은 수의 비트가 들어가기에 비트 밀도는 원판의 안쪽 트랙일수록 더 높은데
바깥쪽 트랙은 비트를 더 집어넣을 수 있음에도 낭비가 되고 있어서
최신 디스크들은 이러한 문제를 방사상 영역으로 구분해 외부 영역의 낭비를 줄인다.
트랙 : 헤드의 위치에 따른 영역
탐색 시간 : 다른 트랙으로 헤드를 옮길 때 걸리는 시간
회전 지연 시간 : 트랙에서 원하는 데이터에 헤드가 위치할 때까지 디스크가 도는 시간
플래시 메모리와 SSD
EEPROM 유형의 매체로 DRAM 처럼 버킷에 전자를 담는 방식으로 작동하지만
더 크고 잘 만들어져 전자가 샐 일이 없지만, 뚜껑을 여닫다 보면 마모되는 문제가 있다.
데이터를 읽을 때는 임의 접근 방식을, 쓸 때는 블록 접근 방식을 사용한다.
최근 디스크 드라이브는 SSD로 교체되고 있는데, 이는 플래시 메모리를 합친 것과 비슷하다.
플래시 메모리는 점차 낡는 문제가 있지만, SSD는 블록의 쓴 횟수를 기억해
모든 블록이 균등하게 낡도록 조정하는 wear leveling 프로세서가 들어있다.
오류 감지와 정정
패리티를 사용하면 효율적으로 단 1비트만 데이터가 잘못된 경우를 감지할 수 있다.
- 데이터에서 1로 설정된 비트의 개수를 카운팅한다.
- 카운트가 짝수인지 홀수인지 나타내는 1비트를 데이터에 덧붙인다.
짝수 패리티
모든 비트를 서로 XOR 한 값을 사용
예 : 1010 → 10100
1의 개수를 짝수로 맞춤
홀수 패리티
XOR 한 값의 보수를 사용
예 : 1010 → 10101
1의 개수를 홀수로 맞춤
패리티 검사 시 출력이 0이면 데이터에 문제가 없거나, 적어도 패리티에는 문제가 없다는 것인데
이는 패리티만 일치하고 오류가 발생하는 경우를 감지할 수는 없다는 뜻이다.
해밍 코드
더 많은 비트를 사용해 더 많은 오류를 감지할 수 있고, 오류 회수가 적은 경우는 즉시 수정도 가능하다.
이를 내장한 오류 검사와 정정 메모리 칩도 존재한다.
checksum
- 데이터를 n 비트 단위로 나눈다.
- 각 n 비트 단위의 데이터를 더한다.
- 더하는 과정에서 발생한 캐리(오버플로우)는 다음 단계에서 처리한다.
- 발생한 캐리를 다시 합산에 추가한다.
- 최종 결과에서 n비트 이하의 값을 추출하여 체크섬을 생성한다.
- 동일한 알고리즘으로 체크섬을 계산해서 무결성을 확인한다.
체크섬의 크기가 클수록 데이터의 작은 변화에도 체크섬이 크게 달라져
위양성 결과가 발생할 가능성이 줄어든다.
순환 중복 검사(CRC), 해시 코드 같은 더 좋은 대체제들도 존재하고
해당 방식들은 데이터의 고유성을 충분히 드러낼 수 있는 방식으로 계산해서
데이터가 약간이라도 바뀌면 검증값이 일치하지 않게 만드는 방식이다.
참고 자료
래치 : 래치에 대한 부분이 이해가 잘 가지 않았는데 그림과 표 예시로 잘 설명해준 글이다.