본문으로 건너뛰기
code0.HDL

BSV 실습

짧은 Bluespec 문제로 핵심 개념을 익혀 보세요. 코드를 수정하고 실행한 다음 풀이를 제출해 보세요.

작성 중인 코드와 완료한 문제는 이 브라우저에 저장됩니다.

장 바로가기

모듈과 인터페이스

문제 1개

모듈 하나와 rule 하나로 된 가장 작은 BSV 프로그램을 실행해 출력을 예측하고, 레지스터 하나와 value method 하나를 가진 모듈과 그것을 읽는 테스트벤치를 읽고 실행한 뒤 한 곳을 바꿔 봅니다.

  1. 14검증 문제카운터 현재 값 읽기value method가 저장된 상태와 다른 값을 반환하는 원인을 찾아 고칩니다.

Bool·Bit와 순수 함수

문제 2개

Bool과 Bit#(n)을 구분하고, 연결·선택·축약 연산으로 비트 벡터를 조립하고 분해하며, 호출한 자리에서 조합 회로가 되는 순수 함수를 작성합니다.

  1. 31검증 문제패리티 프레임 완성하기타입이 있는 비트 필드를 연결하고 축약 연산으로 프레임 패리티를 계산합니다.
  2. 32구현 문제비트 연산 선택하기2비트 선택 값에 따라 두 4비트 값의 AND, OR, XOR, NOR 가운데 하나를 반환합니다.

타입·폭·명시적 변환

문제 3개

크기가 정해진 값이 스스로 폭을 바꾸지 않는 이유, 크기 없는 리터럴이 대상의 폭을 받는 규칙, 0 확장·부호 확장·절단·재해석에 쓰는 함수를 다룹니다.

  1. 10검증 문제바이트를 명시적으로 줄이기허용되지 않는 암묵적 폭 축소를 찾아 명시적 변환으로 고칩니다.
  2. 11구현 문제니블을 0으로 확장하기4비트 입력 위에 0을 배치해 8비트 값을 만듭니다.
  3. 12검증 문제4비트 정수의 부호 확장하기음수 입력의 부호가 사라지는 원인을 찾아 변환을 고칩니다.

선택·case·don't-care 값

문제 1개

?: 연산자, case, 함수로 조합 선택 회로를 만들고, 모든 경로에 값을 주며, 아무도 관찰할 수 없는 자리에만 don't-care 값 ?를 씁니다.

  1. 06구현 문제valid로 쓰이지 않는 payload 보호하기네 개의 유효한 페이로드는 유지하고 나머지 명령은 모두 무효로 표시합니다.

레지스터와 rule 하나

문제 2개

mkReg로 레지스터를 선언하고 rule 하나에서 <=로 쓰며, rule 안의 읽기는 사이클 시작 값을 보고 쓴 값은 다음 사이클에 나타난다는 사실을 확인합니다.

  1. 01구현 문제rule 하나로 세기rule이 사이클마다 한 번씩 세도록 레지스터 갱신을 작성합니다.
  2. 29검증 문제레지스터의 상위 바이트 보존하기상태를 잃는 전체 레지스터 쓰기를 찾아 선택된 쓰기로 바꿉니다.

guard: 유지와 정지

문제 1개

rule의 명시 조건으로 레지스터를 유지하고, 카운터를 한계값에서 정확히 멈추며, 한 rule이 남긴 상태가 다음 rule의 조건을 만족하지 못할 때 생기는 조용한 빈 구간을 찾습니다.

  1. 02검증 문제한계값을 지나치지 않는 카운터세는 rule이 주어진 한계를 넘어 실행되는 원인을 찾아 고칩니다.

상태를 공유하는 rule: 원자성·덮어쓰기·충돌

문제 3개

같은 사이클에 rule 두 개를 놓습니다. 서로 다른 상태를 다루면 둘 다 실행되고, 한 레지스터에 쓴 두 번째 쓰기는 경고와 함께 첫 쓰기를 덮으며, 진짜 충돌에는 읽기/쓰기 순환이 필요합니다. 모든 실행은 하나의 원자적 전이입니다.

  1. 03구현 문제누적과 전달을 두 단계로 나누기겹치지 않는 조건을 두 rule에 주어 각자 자기 차례에 실행되게 합니다.
  2. 19구현 문제두 레지스터를 원자적으로 교환하기하나의 rule이 시작할 때의 값으로 두 레지스터를 교환합니다.
  3. 20검증 문제임의적인 rule 충돌 없애기같은 상태를 두고 다투는 두 rule을 찾아 배타적인 조건을 줍니다.

method: value·Action·ActionValue

문제 4개

결과 타입으로 세 종류의 method를 구분하고, rule에서 호출하며, method 자신의 준비 조건이 호출한 rule의 실행 여부를 어떻게 정하는지 확인합니다.

  1. 15구현 문제카운터 증가시키기Action method 호출 한 번이 수행할 상태 갱신을 구현합니다.
  2. 16구현 문제clear와 enable이 있는 카운터clear와 enable 인자가 카운터의 다음 상태를 결정하는 Action method 하나를 구현합니다.
  3. 17검증 문제현재 티켓 번호 발급하기발급 번호가 현재 값을 건너뛰는 원인을 찾아 반환값을 고칩니다.
  4. 33검증 문제현재 번호표 반환하기ActionValue 식이 현재 번호표 대신 다음 번호표를 반환하는 원인을 찾아 고칩니다.

준비 조건·모듈 인자·합성 경계

문제 1개

매개변수·인자·proviso가 있는 모듈을 정의하고, method의 준비 조건을 헤더에 두어 조건이 거짓이면 호출하는 모든 rule이 멈추게 하며, 스택을 push와 pop으로 추적하고, 합성 경계에서 인터페이스가 지켜야 할 조건을 확인합니다.

  1. 18검증 문제ready condition으로 method 제한하기누락된 method 준비 조건을 추가해 호출자가 한계에서 멈추게 합니다.

사용자 정의 타입

문제 3개

typedef로 설계가 다루는 타입을 정의합니다. 이름만 바꾸는 동의어, 이름 붙은 레이블의 enum, 이름 붙은 필드의 구조체, 태그와 함께 대안 하나를 담는 tagged union을 선언하고, packed 폭을 계산하며, union을 패턴 매칭으로 읽습니다.

  1. 22구현 문제파이프라인 stage 진행하기인코딩이 아니라 레이블을 기준으로 enum을 다음 단계로 옮깁니다.
  2. 23검증 문제요청 필드 읽기요청 구조체를 비트로 변환한 뒤 잘못된 구간을 읽는 코드를 찾아 고칩니다.
  3. 24구현 문제Maybe 값 읽기패턴 매칭으로 Maybe에 저장된 값 또는 0을 반환합니다.

rule로 만드는 상태 기계

문제 1개

설계의 상태에 enum으로 이름을 붙이고, 현재 상태를 레지스터에 두고, guard가 겹치지 않는 상태별 rule을 쓰며, 두 상태 기계를 사이클 단위로 예측합니다.

  1. 21구현 문제두 rule 전이의 순서 정하기스케줄링 충돌을 두 개의 명시적인 원자적 상태 전이로 바꿉니다.

어휘 요소

문제 2개

bsc가 소스를 토큰으로 나누는 규칙과 식별자, 키워드, 주석, 정수·Real·문자열 리터럴, 컴파일러 지시어의 정확한 표기법을 다룹니다.

  1. 04구현 문제잘못된 정수 리터럴 네 개 진단하기컴파일되는 리터럴 오류 네 개를 진단하고 요구된 값을 복구합니다.
  2. 05검증 문제마스크 리터럴의 폭 맞추기모든 비트를 1로 채우는 리터럴을 하위 4비트만 남기는 8비트 마스크로 고칩니다.

패키지

문제 3개

파일 하나가 패키지 하나이며, export가 공개할 이름을, import가 들여올 이름을 정하고, 패키지 경계는 하드웨어 경계가 아니라 이름의 공개 범위라는 사실을 다룹니다.

  1. 07구현 문제value method로 비공개 상태 공개하기패키지가 공개한 관찰 method로 모듈 내부의 비공개 상태를 보고합니다.
  2. 08검증 문제비공개 상수로 method 제한하기게이트가 패키지 비공개 용량을 무시하는 원인을 찾아 guard에 상수를 되돌립니다.
  3. 09구현 문제비공개 패키지 상수 정의하기guard와 두 보고 method가 함께 따르는 패키지 비공개 한도 하나를 정의합니다.

변수·반복문·리터럴의 문맥

문제 2개

변수는 값을 저장하지 않고 이름을 붙이며, 선언된 타입이 크기 미지정 리터럴의 의미를 정하고, 상수 경계의 반복문은 elaboration 중에 정해진 양의 하드웨어로 펼쳐진다는 사실을 다룹니다.

  1. 28구현 문제퍼센트 리터럴 정의하기정수 퍼센트를 10배로 변환하고 유효한 리터럴 범위를 판정하는 함수를 정의합니다.
  2. 30구현 문제제어 흐름으로 1인 비트 세기정적으로 한정된 반복문과 조건문으로 바이트에서 1인 비트를 셉니다.

타입클래스와 proviso

문제 4개

타입클래스는 오버로드 연산의 묶음에 이름을 붙이고, 인스턴스는 타입별 구현을 제공하며, proviso는 다형 정의가 필요로 하는 인스턴스와 폭 관계를 선언하는데, 이 모두가 컴파일 시점에 결정되어 선택 회로를 만들지 않습니다.

  1. 13구현 문제다형 값을 pack하기Bits proviso가 있는 모든 값을 pack한 비트를 반환합니다.
  2. 25구현 문제타입클래스 인스턴스 구현하기다형 Priority proviso가 사용하는 RequestKind 우선순위 동작을 정의합니다.
  3. 26구현 문제폭 검사를 만족하는 suffix 만들기Add proviso가 결과 폭을 제약하는 연결식을 완성합니다.
  4. 27검증 문제직접 작성한 Bits 인스턴스 고치기pack이 정한 프로토콜 인코딩과 어긋나는 디코딩을 찾아 고칩니다.

패턴 매칭

문제 3개

패턴으로 구조화된 값을 분해합니다. 상수·변수·와일드카드 패턴, struct와 tagged union 패턴, 패턴 매칭 case, 조건 안의 패턴 검사, match 선언을 다룹니다.

  1. 35구현 문제중첩된 요청에서 payload 꺼내기태그가 있는 패킷을 검사하고 struct 페이로드의 필드 하나를 바인딩합니다.
  2. 36검증 문제경계 opcode 제외하기범위를 하나 넘은 페이로드까지 허용하는 경계 포함 패턴 필터를 찾아 고칩니다.
  3. 37구현 문제튜플 필드 두 개 분해하기매치 대입으로 타입이 있는 튜플 필드 두 개를 바인딩해 다시 결합합니다.

값으로 다루는 rule

문제 1개

rule을 Rules 값으로 만들어 addRules로 모듈에 추가하고, elaboration에서 한 번 일어나는 호출과 추가된 rule이 실행되는 여러 사이클을 구분합니다.

  1. 34구현 문제상한이 있는 rule 식 만들기레지스터를 주어진 한계까지 증가시키는 재사용 가능한 Rules 값을 반환합니다.

StmtFSM으로 만드는 유한 상태 기계

문제 3개

여러 사이클에 걸친 과정을 Stmt로 적고 mkFSM으로 실행하는 방법과 그 동작, 곧 seq에서 Action 하나가 반영되는 단계 하나라는 규칙, repeat·while·for 반복, await 대기, par 분기, 시작한 실행이 끝난 뒤에만 종료하는 방법을 다룹니다.

  1. 38구현 문제FSM 단계 두 개를 순서대로 실행하기둘째 액션이 첫 액션의 결과를 읽는 순차 문장을 만듭니다.
  2. 39검증 문제FSM 동작 네 번 반복하기반복되는 FSM 본문이 필요한 횟수보다 한 번 일찍 끝나는 원인을 찾아 고칩니다.
  3. 40검증 문제준비된 뒤에만 완료하기FSM이 기다리는 작업보다 먼저 완료를 보고하는 원인을 찾아 고칩니다.

FIFO·split·라이브러리 primitive

문제 3개

대부분의 설계가 쓰는 라이브러리 요소를 계약으로 읽습니다. 결과 타입이 분할 위치를 정하는 split과 튜플, implicit condition으로 호출자를 기다리게 하는 FIFO method, 준비 상태를 값으로 알리는 FIFOF 플래그, 시뮬레이션에만 있는 시스템 태스크를 다룹니다.

  1. 41구현 문제결과 폭으로 프레임 나누기12비트 프레임을 4비트 종류와 8비트 페이로드로 나누는 method를 구현합니다.
  2. 42구현 문제FIFO 항목을 들어온 순서대로 꺼내기가장 오래된 바이트를 반환하고 제거하는 큐 method를 완성합니다.
  3. 43검증 문제FIFOF가 데이터를 받을 수 있는지 알리기비어 있는 탄력 큐가 데이터를 받을 수 없다고 보고하는 원인을 찾아 고칩니다.

어트리뷰트로 컴파일러 제어하기

문제 3개

요청·증명되는 단언·신뢰되는 단언으로 나뉘는 어트리뷰트, synthesize와 noinline 경계, always_ready·always_enabled를 포함한 포트 이름 어트리뷰트, descending_urgency·execution_order·preempts와 rule 단언 같은 스케줄링 어트리뷰트, split과 클록·리셋·doc 어트리뷰트를 다룹니다.

  1. 44검증 문제잘못된 always-ready 계약 고치기유한 버퍼의 enqueue method와 모순되는 준비 상태 선언을 제거합니다.
  2. 45구현 문제action method를 always enabled로 만들기조건 없는 tick method를 항상 활성화되는 RTL 프로토콜로 선언합니다.
  3. 46검증 문제잘못된 implicit condition 계약 고치기큐 상태에 의존하는 rule과 모순되는 스케줄링 단언을 제거합니다.

BSV 설계에 RTL 포함하기

문제 3개

타입이 있는 BSV와 외부 RTL을 잇는 import "BVI" 계약, enable·ready를 포함한 value method와 Action method 대응, default_clock과 default_reset, 모든 method 쌍의 schedule 관계, 정적 파라미터, 그리고 실패가 BSC 컴파일·Verilog elaboration·시뮬레이션 가운데 어디서 생겼는지 찾는 방법을 다룹니다.

  1. 47구현 문제가져온 RTL에 쓰는 값 연결하기고정된 가져온 레지스터 래퍼가 사용하는 수정할 수 있는 값 연결을 완성합니다.
  2. 48검증 문제가져온 RTL에서 읽은 값 연결하기가져온 RTL의 읽기 결과를 전달하는 함수에서 값이 사라지는 원인을 찾아 고칩니다.
  3. 49구현 문제가져온 RTL의 parameter 설정하기고정된 BVI 매개변수 연결에 필요한 초깃값을 전달합니다.

BSV 설계에 C 포함하기

문제 3개

import BDPI로 BSV에서 C 함수를 호출합니다. 선언, 양쪽이 보는 전달 타입, packed 값과 넓은 값, 다형적 import, 반환 형태, 경계에서 생기는 오류의 모습을 다룹니다.

  1. 50구현 문제스칼라 BDPI carrier 폭 줄이기32비트 BSV 값을 가져온 C 함수에 필요한 8비트 전달 타입으로 변환합니다.
  2. 51검증 문제부호 있는 값의 비트 보존하기BDPI 어댑터가 부호 있는 BSV 값의 2의 보수 표현을 잃는 원인을 찾아 수정합니다.
  3. 52구현 문제다형 벡터의 폭 전달하기구체적인 C 경계에 필요한 명시적 폭 인자를 계산합니다.