본문으로 건너뛰기
code0.HDL

34구현 문제

상한이 있는 rule 식 만들기

1. 문제와 수정 범위

countToBound는 전달받은 레지스터와 상한을 참조하는 Rules 값을 반환해야 합니다. 반환된 rule은 count를 상한까지 1씩 늘리고 상한에서 멈춥니다. starter의 빈 rules 블록도 유효한 값이어서 컴파일은 되지만, addRules가 설치할 rule이 없습니다. 그래서 공개 출력의 count는 4까지 늘지 않고 0에 머뭅니다.

기존 rules와 endrules 사이에 rule 하나만 추가하세요. 함수 인자, Rules 반환 타입, addRules 호출, 출력과 종료를 맡은 rule, mkTop은 그대로 둡니다.

2. starter 읽기와 실행 전 예측

이 파일의 동작은 두 시점으로 나뉩니다.

시점일어나는 일
elaborationcountToBound(count, 4)가 Rules 값을 만들고 addRules가 현재 모듈에 설치합니다
시뮬레이션설치된 rule이 사이클마다 guard를 평가하고 레지스터 쓰기를 예약합니다

함수 호출 자체가 사이클마다 레지스터를 늘리지는 않습니다. 함수는 나중에 실행될 rule 정의를 반환할 뿐입니다.

실행 전에 출력을 예측해 보세요. advance는 cycle을 늘리며 출력하지만, 빈 Rules는 count를 바꾸지 못하므로 모든 줄에서 count = 0입니다. 실행 결과로 확인한 뒤 수정 위치를 빈 블록 안으로 한정하세요.

3. 최소 수정과 완료 조건

추가할 rule의 guard는 count가 상한보다 작을 때 참이고, 상한과 같을 때 거짓이어야 합니다. 본문은 다음 값을 한 번만 예약합니다. 레지스터를 새로 만들거나, 상한 검사를 항상 실행되는 본문 안의 if로 옮기거나, 동작을 mkTop에 넣으면 이 연습에서 요구하는 guard 기반 rule 식의 구조를 벗어납니다.

수정한 뒤에는 마지막 줄만 보지 말고 출력 전체를 확인하세요. 초깃값 0과 상한 4에서 시작 상태 0, 1, 2, 3은 각각 1, 2, 3, 4를 예약합니다. 상태 4에서는 guard가 거짓이므로 이후 여러 사이클 동안 4가 유지됩니다.

조건기대 동작
상한 40에서 4까지 1씩 증가한 뒤 4 유지
더 작거나 큰 상한같은 함수가 전달된 상한에서 정확히 멈춤
상한 0처음부터 guard가 거짓이어서 0 유지
상한 도달 뒤 여러 사이클상한을 넘는 쓰기가 없음

반환하는 rule 안에 4를 상수로 쓰면 다른 상한에서 실패합니다. 같음을 포함하는 비교를 guard로 쓰면 상한에서 한 번 더 실행되어 값이 상한을 넘습니다.

4. 단계형 힌트

힌트 1: 반환할 대상

함수는 elaboration 중에 레지스터를 늘리지 않습니다. 나중에 레지스터를 늘릴 rule 정의를 Rules 값으로 반환해야 합니다.

힌트 2: 경계에서 guard 검사하기

후보 비교식에 count = bound - 1과 count = bound를 각각 넣어 보세요. 첫 번째 상태에서만 참이 되는 비교가 필요합니다.

힌트 3: 작성 위치와 형태

기존 rules 블록 안에 이름 있는 rule을 선언하세요. 괄호 안 guard에는 비교식을 두고, 본문에는 레지스터 대입 하나를 둡니다.

5. 추가 실험

수정을 마친 뒤 별도 사본에서 레지스터 두 개에 같은 함수를 서로 다른 상한으로 설치해 보세요. 두 레지스터가 증가하다 멈추는 사이클을 실행 전에 계산해 보세요. 함수 정의 하나가 elaboration에서 서로 다른 rule 인스턴스를 만든다는 것을 확인한 뒤 mkTop을 되돌리세요.

개념 다시 보기
준비
Main.bsv