레지스터·카운터·상태기계
레지스터·시프트 레지스터·카운터와 유한상태기계를 다음 상태 규칙으로 설계합니다.
4비트 계산 결과를 다음 명령까지 보관하려면 플립플롭 네 개를 묶을 수 있습니다. 같은 클록을 사용해 한 값으로 읽고 쓰는 저장 묶음을 레지스터라고 합니다. 어떤 값을 언제 넣을지 제어 신호를 함께 설계해야 합니다.
병렬 적재와 시프트
4비트 레지스터 Q에 load=1이면 입력 D를 적재하고, load=0이면 Q를 유지합니다. 입력 앞의 MUX가 D와 기존 Q를 고르면 이 규칙을 만들 수 있습니다. 리셋은 초기 상태를 지정하며 동기·비동기 방식의 타이밍을 구분해야 합니다.
시프트 레지스터는 각 비트를 이웃 자리로 옮깁니다. 오른쪽 논리 시프트에서 1010은 0101이 됩니다. 직렬 입력은 한 번에 한 비트, 병렬 입력은 여러 비트를 함께 전달합니다. 원문의 직렬·병렬 전송은 이 차이로 연결해서 이해할 수 있습니다.
카운터는 다음 상태를 계산합니다
2비트 업 카운터의 상태는 00→01→10→11→00입니다. 출력 비트가 차례로 전파되는 리플 카운터와 같은 클록 에지에서 갱신하는 동기 카운터의 지연 특성은 다릅니다. 현재 상태+1의 하위 2비트를 저장하는 모델이라면 3 다음이 0입니다.
상태기계로 잠금 장치 만들기
유한상태기계(FSM)는 유한한 상태와 입력에 따라 다음 상태·출력을 정한 모델입니다. 카드 승인 후 문이 열리고, 닫힘 센서를 받으면 다시 잠그는 장치를 생각합니다. 상태는 LOCKED·OPEN 두 개면 됩니다.
| 현재 상태 | 입력 | 다음 상태 | 전이 후 잠금 출력 |
|---|---|---|---|
| LOCKED | 유효 카드 | OPEN | 해제 |
| LOCKED | 그 외 | LOCKED | 잠금 |
| OPEN | 닫힘 센서 | LOCKED | 잠금 |
| OPEN | 그 외 | OPEN | 해제 |
이 표의 출력은 클록 에지에서 다음 상태가 적용된 뒤의 값입니다. 에지 전 LOCKED 상태에서는 유효 카드 입력이 들어와도 아직 잠금이며, 에지에서 OPEN으로 전이한 뒤 해제됩니다. 따라서 이 모델은 상태로 출력을 결정하는 Moore 방식입니다. 상태와 현재 입력으로 출력이 결정되는 Mealy 방식도 있습니다. 출력의 정의와 타이밍을 명시하면 두 모델을 서로 다른 목적으로 쓸 수 있습니다. 실제 문에는 비상 해제·센서 고장 조건도 필요하지만 이 예제는 기본 상태 전이만 모델링합니다.
def next_state(state, event):
if state == "LOCKED":
return "OPEN" if event == "VALID_CARD" else "LOCKED"
if state == "OPEN":
return "LOCKED" if event == "CLOSED" else "OPEN"
raise ValueError("알 수 없는 상태")
state = "LOCKED"
trace = []
for event in ["INVALID_CARD", "VALID_CARD", "NONE", "CLOSED"]:
state = next_state(state, event)
trace.append(state)
assert trace == ["LOCKED", "OPEN", "OPEN", "LOCKED"]코드는 물리적 센서 지연을 검사하지 않습니다. 먼저 전이 규칙의 빈틈을 찾는 데 사용합니다.
독립 문제: 세 번 클릭하면 완료
버튼을 누른 사건마다 상태가 0→1→2→DONE으로 진행하고, DONE에서는 추가 버튼을 무시합니다. reset 사건은 어느 상태에서든 0으로 만듭니다. press, press, reset, press, press, press, press의 상태열을 쓰고 상태 저장에 필요한 최소 비트를 구하세요.
힌트
DONE을 0으로 자동 순환시키는 카운터와 구분하세요. 상태는 네 가지입니다.
풀이
상태열은 1·2·0·1·2·DONE·DONE입니다. 2비트면 네 상태를 구분합니다. DONE에서 다시 0으로 갔다면 마지막 상태의 유지 규칙을 빠뜨린 것입니다. 다음 JK 입력식과 동기 카운터에서는 목표 전이에서 입력식·논리 연결까지 설계합니다.