본문으로 건너뛰기
code0.HDL

45구현 문제

action method를 always enabled로 만들기

1. 문제와 수정 범위

FreeRunningCounter.tick은 매 사이클 반드시 실행되는 동작으로 선언되어야 합니다. tick 본문에는 guard가 없고, 상태에 따라 준비 여부가 바뀌는 method도 호출하지 않습니다. mkTop의 drive도 조건 없이 매 사이클 tick을 호출합니다. 그런데 인터페이스는 아직 tick을 Enable 입력이 있는 일반 Action method로 선언하고 있습니다.

인터페이스의 tick 선언만 수정하세요. method 본문, 카운터 레지스터, count, mkTop은 그대로 둡니다.

2. starter 읽기와 실행 전 예측

인터페이스, 구현, 호출하는 쪽 순서로 읽어 보세요.

읽을 곳확인할 계약
tick 선언생성될 포트 프로토콜을 정하는 어트리뷰트가 있는지
tick 구현준비 여부를 제한하는 guard나 내부 method 호출이 있는지
drive모든 사이클에 실행되는지
advance, showcycle이 언제 3이 되고 값을 언제 읽는지

실행 전에 결과를 예측해 보세요. 일반 Enable 프로토콜도 유효하므로 starter는 컴파일과 시뮬레이션에 성공하고, show 전에 지난 사이클마다 카운터가 1씩 늘어난 값이 출력됩니다. 틀린 것은 산술 결과가 아닙니다. 생성된 RTL에서 외부 호출자가 tick을 생략할 수 있다는 점이 문제입니다.

3. 최소 수정과 완료 조건

tick이 매 사이클 모듈 동작에 포함된다는 method 프로토콜을 선언하세요. 인터페이스 선언 한 곳만 고칩니다. guard를 추가하거나, 호출을 복제하거나, 갱신식을 바꾸어 데이터 경로에서 프로토콜을 흉내 내지 마세요.

tick은 모든 상태에서 준비되어 있고 drive는 모든 사이클에 이 method를 호출합니다. 따라서 Enable 입력을 없애도 호출되는 쪽과 호출하는 쪽의 동작이 그대로 맞습니다. 이 프로토콜에는 항상 준비되어 있다는 조건도 함께 들어 있습니다.

수정한 뒤 실행은 성공해야 하고, 출력되는 count는 show 전에 끝난 사이클마다 한 번씩 증가한 값이어야 합니다. mkFreeRunningCounter를 따로 합성하면 tick의 Enable 입력이 없어야 하고, count는 읽기 전용 value method로 남아야 합니다. delta가 1인 공개 실행만 맞추어서는 충분하지 않습니다. 0과 8비트 범위를 넘어 되돌아가는 값을 포함한 모든 delta에서 한 사이클에 한 번 같은 덧셈을 수행해야 합니다.

4. 단계형 힌트

힌트 1: 없앨 신호 구분하기

일반 Action method의 Enable은 호출자가 동작을 요청한다는 뜻입니다. 이 문제에서는 동작이 매 사이클 필수이므로 요청 신호 자체를 없앱니다. 요청 신호의 이름을 바꾸는 것이 아닙니다.

힌트 2: 선언 위치 좁히기

프로토콜 어트리뷰트는 FreeRunningCounter 인터페이스의 tick 선언 바로 앞에 둡니다. 구현 쪽 method에는 따로 붙일 것이 없습니다.

힌트 3: 어트리뷰트 고르기

값 없이 쓰는 method 어트리뷰트 가운데 이름이 "항상 enable된다"는 뜻인 것을 쓰세요. 이 어트리뷰트는 항상 준비되어 있다는 성질도 함께 뜻합니다.

5. 추가 실험

필수 수정을 마친 뒤 drive에 cycle < 2 guard를 잠시 붙인다고 가정해 보세요. method 본문은 여전히 항상 준비되어 있지만 호출자가 매 사이클 호출하지 않습니다. 이때 어떤 프로토콜 조건이 깨지는지 예측해 보세요. 채점 대상이 아니므로 실험한 변경은 제출하기 전에 되돌리세요.

개념 다시 보기
준비
Main.bsv