5 / 24 · 개념
레지스터 전송을 에지 기준으로 읽기
이전 상태와 다음 상태를 나누고 enable이 값을 보존하는 조건을 추적합니다.
내용은 무료로 볼 수 있습니다. 수강 신청하면 학습 기록을 저장할 수 있어요.
한 에지에서는 이전 상태를 함께 읽는다
레지스터 전송 설계에서는 사이클 사이에 살아 있어야 하는 정보를 먼저 찾습니다. 누산기 acc, 입력 피연산자, 반복 횟수 count, 출력 valid는 모두 시간이 지나도 보관해야 하는 상태입니다. 반면 sum=acc+operand는 현재 상태에서 계산할 수 있는 조합 값입니다. '변수를 썼다'는 사실만으로 하드웨어 저장소가 생기지 않습니다. 어떤 이벤트에서 어떤 값을 저장할지가 저장소의 행동을 결정합니다.
다음 누산기는 en=1인 상승 에지에만 입력 x를 더합니다. en=0이면 acc를 그대로 보존합니다. 9비트로 넓힌 합에서 하위 8비트를 선택하므로 계약은 modulo 256입니다. always_ff의 nonblocking 대입은 이번 에지에 읽은 이전 acc를 사용하여 다음 acc를 예약합니다. 같은 블록에 쓰인 코드 줄을 소프트웨어의 즉시 대입 순서로 해석하면 여러 레지스터가 있는 파이프라인을 잘못 이해하게 됩니다.
logic [7:0] acc;
logic [8:0] next_sum;
assign next_sum = {1'b0, acc} + {1'b0, x};
always_ff @(posedge clk) begin
if (rst) acc <= 8'd0;
else if (en) acc <= next_sum[7:0];
endreset은 동기식이며 해당 상승 에지에서 en보다 우선합니다. 이 구조에서 en=0일 때 대입을 생략하는 것은 레지스터 hold의 의미입니다. 조합 always_comb에서 일부 경로의 대입을 생략하면 이전 조합 값을 기억하는 latch가 의도치 않게 필요해질 수 있으므로 두 상황을 혼동하지 않습니다. 조합 next-state 계산은 먼저 기본값을 주고 조건별로 바꾸는 방식이 읽기 쉽습니다.
| 에지 | rst | en | x | 에지 전 acc | 에지 후 acc |
|---|---|---|---|---|---|
| 0 | 1 | 1 | 9 | 알 수 없음 | 0 |
| 1 | 0 | 1 | 7 | 0 | 7 |
| 2 | 0 | 0 | 100 | 7 | 7 |
| 3 | 0 | 1 | 250 | 7 | 1 |
에지 2의 x=100은 수락하지 않았으므로 합에 포함되지 않습니다. 에지 3에서는 7+250=257을 8비트로 축소하여 1을 저장합니다. '입력 값이 화면에 있었음'과 '입력이 수락되었음'을 구분해야 정지 사이클의 테스트가 맞습니다. 이 구분은 나중에 en을 valid와 ready의 AND로 바꿔도 유지됩니다.
두 레지스터 a와 b에서 a<=x; b<=a;를 실행하면 b에는 이번 x가 아니라 에지 전 a가 들어갑니다. 예를 들어 이전 a=5, x=9이면 에지 후 a=9, b=5입니다. 두 상태를 실제로 분리하려는 의도라면 맞는 행동이며, b에 9를 넣고 싶었다면 b의 입력을 x로 연결해야 합니다. 디버깅 시 에지 전 표를 완성하고 모든 다음 값을 한꺼번에 채우는 습관을 들이면 데이터와 제어의 한 사이클 어긋남을 쉽게 찾습니다.
직접 생각해 보기
초기 a=4, b=0에서 두 에지의 x가 각각 8과 12입니다. 매번 a<=x; b<=a가 실행되면 두 번째 에지 후 a,b는 무엇인가요?
해설 보기
첫 에지 후 a=8,b=4이고 둘째 에지 후 a=12,b=8입니다. b는 각 에지 전 a를 저장합니다. 둘째 에지의 x=12는 같은 에지에 b로 바로 넘어가지 않습니다.