16구현 문제
clear와 enable이 있는 카운터
1. 목표와 계약
mkClearEnableCounter는 4비트 상태 q를 유지하고 value로 반환합니다. 호출자는
Action method step(clear, enable)을 한 사이클에 최대 한 번 호출합니다. 두 인자가 다음
사이클의 value를 결정합니다.
clear | enable | 다음 value |
|---|---|---|
True | 무관 | 0 |
False | True | q + 1, 15 다음은 0 |
False | False | q 유지 |
step이 호출되지 않은 사이클에서도 q는 유지됩니다. mkReg(0)은 모듈 리셋 값입니다.
리셋은 실행 환경이 시작할 때 한 번 적용합니다. clear는 호출자가 언제든 올릴 수 있는
기능 입력이며, 리셋 없이도 동작해야 합니다.
앞의 rule 하나로 세기 문제의 카운터는 스스로 세고 5에서 멈춥니다. 이 문제의 카운터는
계약이 다릅니다. enable이 지시할 때만 세고, 스스로 멈추지 않으며, 15 다음에 0이 됩니다.
수정 범위는 mkClearEnableCounter 안의 TODO 두 곳입니다. 인터페이스, 레지스터 선언,
mkTop은 그대로 두세요.
2. starter 읽기와 예측
mkTop은 열 사이클 동안 매 사이클 value를 출력한 뒤 step을 한 번 호출합니다. drive
rule의 clear와 enable 식을 읽고, 실행하기 전에 출력될 열 개 값을 표로 적어 보세요.
starter의 value는 ?를 반환하고 step은 q에 아무것도 기록하지 않습니다. 모든 줄에
같은 임의 숫자가 출력될 것이라고 예측한 뒤 한 번 실행해 확인하세요.
3. 구현과 실행 결과 해석
value는 레지스터를 반환합니다. step은 레지스터에 최대 한 번 기록합니다. clear를
먼저 판정하고, 그다음 enable을 판정하고, 남은 경우에는 기록하지 않습니다. <=는 기록을
예약하므로 현재 사이클에는 이전 상태가 출력되고 다음 사이클에 새 상태가 보입니다.
수정한 설계를 실행하면 clear가 올라간 다음 사이클에 0이 보여야 합니다. enable이 켜진
사이클마다 1씩 증가하고, 두 인자가 모두 꺼진 구간에서는 값이 유지되어야 합니다.
4. 완료 조건
- 리셋 직후
value는 0입니다. step(True, _)은enable과 현재 상태에 관계없이 다음value를 0으로 만듭니다. 세는 도중에도 같습니다.step(False, True)는 정확히 1씩 증가시키고, 15 다음에는 0입니다.step(False, False)와 호출이 없는 사이클은value를 바꾸지 않습니다.clear뒤에는 0부터 다시 셉니다.- 인터페이스와
Bit#(4)폭은 그대로입니다.
5. 단계형 힌트
힌트 1
표의 세 행 가운데 두 행은 레지스터에 기록하고 한 행은 기록하지 않습니다. Action method
안의 if는 나머지 분기를 비워 둘 수 있습니다. 기록이 없으면 레지스터는 값을 유지합니다.
힌트 2
clear를 enable보다 먼저 검사하도록 조건 순서를 정하세요. enable을 먼저 검사하면
같은 사이클에 들어온 clear가 무시됩니다.
힌트 3
4비트 산술은 이미 순환합니다. 4'd15에 1을 더하면 4'd0입니다. 15와 비교하는 조건은
필요하지 않으며, 그 조건이 세기를 멈추면 계약을 위반합니다.
6. 추가 실험
q와 value의 폭을 함께 Bit#(3)으로 바꾸고 공개 실행으로 clear 우선순위와 값 유지를
다시 확인해 보세요. 공개 실행은 값이 7에 도달하기 전에 초기화하므로 순환은 보여 주지
않습니다. 임시 코드에서 상태 0부터 step(False, True)를 여덟 번 연속 호출하고, 각 호출
뒤의 상태를 예측해 보세요. step을 고치지 않아도 15가 아니라 7 다음에 0으로 순환해야
합니다. 제출하기 전에 Bit#(4)로 복원하세요.