Altifigence Academy

15 / 20 · 실습

실습: backpressure와 리셋

전역 정지, 결과 보관, 중단한 작업의 초기화를 실행해 확인합니다.

단순하지만 완전한 흐름 제어

작은 학습 배열에서는 모든 입력 스케줄과 PE 상태를 함께 멈추는 전역 advance를 사용합니다. 입력 버퍼가 다음 논리 단계의 묶음을 준비했을 때만 advance합니다. 일부 경계 lane이 원래 invalid인 단계는 그 lane에 데이터를 요구하지 않습니다. 한 축만 진행하면 스큐가 무너지므로 PE 일부만 멈추는 신호는 이 설계에 넣지 않습니다. 독립 ready/valid 링크가 필요하다면 이중 입력 버퍼와 매칭·대기 규칙을 새로 설계해야 합니다.

출력에는 valid/ready 계약을 따로 둡니다. 결과가 준비되면 valid=1과 데이터를 유지하고, valid&&ready인 에지에서 한 번만 전달합니다. 소비자가 ready=0이면 데이터와 job 태그가 바뀌면 안 됩니다. 이 과정의 단순 래퍼는 결과를 아직 전달하지 않은 동안 새 작업을 시작하지 않습니다. 계산 중 소비자의 ready를 직접 필요로 하지는 않으며, 충분한 결과 버퍼가 있는 경우 계산은 계속할 수 있습니다.

실행해서 우선순위 확인하기

아래를 stall-lab.mjs로 저장하고 node stall-lab.mjs로 실행합니다. 이는 두 항짜리 한 PE 작업과 결과 레지스터의 제어 참조입니다. 전체 배열에서는 같은 advance로 모든 PE와 경계 스케줄을 묶습니다. 외부 패키지 없이 Stall/reset lab passed가 출력되어야 합니다.

javascript
import assert from 'node:assert/strict';
let s;
function reset(){s={step:0,acc:0,valid:false,data:0,job:7};}
const pairs=[[-2,3],[4,-5]];
function tick({advance=true,ready=false,rst=false}={}) {
 if(rst){reset();return null;}
 if(s.valid){
  if(!ready)return null;
  const out={data:s.data,job:s.job};s.valid=false;return out;
 }
 if(advance && s.step<pairs.length){
  const [a,b]=pairs[s.step];s.acc+=a*b;s.step++;
  if(s.step===pairs.length){s.data=s.acc;s.valid=true;}
 }
 return null;
}
reset();tick();
assert.equal(s.acc,-6);
const held={...s};tick({advance:false});
assert.deepEqual(s,held);
tick();assert.equal(s.data,-26);assert.equal(s.valid,true);
const blocked={...s};tick({ready:false});tick({ready:false});
assert.deepEqual(s,blocked);
assert.deepEqual(tick({ready:true}),{data:-26,job:7});
assert.equal(tick({ready:true}),null);
reset();tick();tick({rst:true,advance:false});
assert.deepEqual(s,{step:0,acc:0,valid:false,data:0,job:7});
tick();tick();assert.equal(s.data,-26);
console.log('Stall/reset lab passed');

첫 MAC은 −6을 만들고 정지 동안 step도 유지됩니다. 두 번째 MAC은 최종 −26을 결과 레지스터에 복사합니다. ready=0인 두 에지에서 valid와 data가 유지되고, ready=1인 에지에서 한 번만 결과를 내보냅니다. 다음 에지에 같은 결과를 다시 보내지 않습니다. reset은 중간 작업의 acc와 step·결과 valid를 모두 지우므로 작업을 처음부터 다시 실행해야 합니다.

배열에 적용할 검사

배열 실습에서 얻은 4단계 스케줄에 두 번의 전역 pause를 넣으면 계산은 4 advance 에지, 경과 시간은 6 물리 에지가 됩니다. 완료 에지 번호 공식은 논리 단계에서 그대로이고 실제 클록 번호는 pause 위치에 따라 이동합니다. 스톨을 넣어도 각 PE의 k 소비 목록과 최종 행렬은 같아야 합니다. 랜덤 pause 시험은 처리율 숫자를 만드는 것이 아니라 상태 유지와 정렬을 검증합니다.

reset 중에는 미완성 결과를 성공으로 전달하지 않습니다. 외부 래퍼가 중단을 알릴 필요가 있으면 job을 실패·취소 상태로 별도 보고하고, 새 작업 전에 입력 버퍼도 비웁니다. 이 실습의 reset은 전체 학습 상태를 즉시 초기화하는 동기 참조입니다. 실제 RTL의 리셋 동기화, 클록 도메인 경계와 물리 타이밍 요구는 별도 설계 항목입니다. 단순 모델 성공이 설치된 앱이나 실물 하드웨어의 동작 증거가 되지는 않습니다.

ready를 내리는 시험에서는 출력 값을 새로 계산하지 않습니다. 보관된 결과를 그대로 유지하고 소비자가 수락한 횟수만 센다는 점이 핵심입니다. reset과 ready가 같은 에지에 오면 여기서는 reset이 우선하여 결과를 전달하지 않습니다. 시스템이 다른 우선순위를 요구하면 수신 측과 함께 계약을 변경해야 합니다.

직접 생각해 보기

결과 valid=1, ready=0을 세 에지 유지한 뒤 ready=1로 바꿉니다. 세 대기 에지에서 유지할 신호와 전송 횟수는? reset이 대기 중 들어오면?

해설 보기

data·job·valid를 모두 유지하며 대기 중 전송은 0회, ready=1 에지에서 1회입니다. reset이면 pending 결과 valid를 지우고 그 작업을 성공 전달하지 않습니다. 취소 알림이 필요하면 별도 상태 계약을 사용합니다.

실습 파일

stall-lab.mjs ↓

선택은 이 브라우저에만 적용됩니다. 언제든 푸터에서 변경할 수 있습니다.