49 / 52 · Conceito
Pipelining multiply-add with aligned operands
연산을 레지스터 경계로 나누고 데이터·valid·보조 피연산자가 같은 거래에 속하도록 설계합니다.
As aulas podem ser lidas gratuitamente. Inscreva-se para salvar o progresso.
A tradução ainda não está disponível. A aula original é exibida. (한국어)
계산식에서 두 개의 단계로
선수 지식: signed 산술, nonblocking 대입, setup 조건, valid 신호.
각 입력 거래가 signed 8비트 a·b와 signed 16비트 c를 포함하며, 결과는 다음 식이라고 합시다. 누적기가 아니라 각 거래를 독립적으로 처리하는 multiply-add입니다.
8비트 곱의 정확한 결과에는 16비트가 필요합니다. 여기에 c를 더할 때 16비트끼리 계산하고 나중에 늘리면 이미 잃은 상위 비트를 복구할 수 없습니다. 두 피연산자를 먼저 17비트로 부호 확장한 뒤 더합니다.
1단계에서 곱과 c를 함께 저장하고, 2단계에서 같은 거래의 두 값을 더합니다. c를 지연하지 않으면 이전 거래의 곱에 현재 거래의 c가 섞이는 오류가 생깁니다.
module multiply_add_pipeline (
input logic clk, rst, in_valid,
input logic signed [7:0] a, b,
input logic signed [15:0] c,
output logic out_valid,
output logic signed [16:0] y
);
logic v1;
logic signed [15:0] p1, c1;
logic signed [16:0] p_ext, c_ext;
assign p_ext = {p1[15], p1};
assign c_ext = {c1[15], c1};
always_ff @(posedge clk) begin
if (rst) begin
v1 <= 1'b0;
out_valid <= 1'b0;
end else begin
v1 <= in_valid;
out_valid <= v1;
if (in_valid) begin
p1 <= a * b;
c1 <= c;
end
if (v1) y <= p_ext + c_ext;
end
end
endmodule이 인터페이스는 매 에지 입력을 받을 수 있고, 수신 측도 출력을 항상 받을 수 있다고 가정합니다. out_valid=0인 y는 비교하지 않습니다. 데이터 레지스터를 리셋하지 않아도 valid를 초기화하면 사용하지 않는 데이터를 구별할 수 있습니다.
‘두 단계’와 관찰 시점을 구분합니다
아래 표는 각 에지에서 입력을 받아 에지 직후의 레지스터 상태를 기록한 것입니다. A와 B는 서로 다른 거래입니다.
| 에지 | 수락 입력 | 1단계 | 출력 레지스터 |
|---|---|---|---|
| E0 | A | A의 곱과 c | invalid |
| E1 | B | B의 곱과 c | A의 결과, valid |
| E2 | 없음 | invalid | B의 결과, valid |
| E3 | 없음 | invalid | invalid |
A의 결과는 E1 직후 준비됩니다. 같은 클록의 다음 회로는 E2에서 그것을 샘플링합니다. 따라서 입력 수락 E0부터 출력 수신 E2까지는 두 주기입니다. 출력 레지스터가 바뀌는 시점과 다음 회로가 수신하는 시점을 섞어서 지연을 설명하지 마세요.
각 열은 한 상승 에지의 관찰 기록입니다. 입력은 에지 직전, 이름에 after가 붙은 상태는 갱신 직후 값입니다. 열의 정렬은 샘플 순서를 나타내며 물리적인 전파 지연을 그린 것이 아닙니다. 거래 A=(2,3,10), B=(4,5,100)입니다. 1단계는 곱과 c를 함께 저장하고 다음 에지에 이전 단계끼리 더합니다. 대시는 invalid 구간입니다.
View waveform data
| Signal | Wave | Bus values |
|---|---|---|
| edge | 2345 | E0 → E1 → E2 → E3 |
| accepted | 234. | A → B → - |
| product1 after | 234. | 6 → 20 → - |
| c1 after | 234. | 10 → 100 → - |
| y after | 2345 | - → 16 → 120 → - |
| out_valid after | 01.0 |
파이프라인을 나누면 얼마나 빨라질까요?
곱셈 지연 3.2ns, 덧셈 지연 1.1ns, 레지스터 오버헤드 0.2ns인 단순 모델을 생각합니다. 이 값들은 계산용 가정입니다.
최대 주파수의 상한은 약 222MHz에서 294MHz로 바뀝니다. 두 단계라고 처리율이 반드시 두 배가 되지는 않습니다. 가장 느린 단계와 레지스터 비용이 주기를 결정합니다. 실제 결과는 합성·배치·제약에 따라 달라집니다.
검증은 거래 단위로 합니다
입력을 받을 때 정수 참조 모델의 a×b+c를 큐에 넣습니다. 출력 valid가 수신되는 에지에서 앞의 기대값을 꺼내 비교합니다. in_valid가 0인 구간도 끼워 넣어 bubble이 데이터와 함께 이동하는지 확인하세요. c만 매 거래 크게 바꾸는 패턴은 지연 누락을 잘 드러냅니다.
Experimente
연속된 거래 A=(a=3,b=-4,c=10), B=(a=2,b=5,c=100)를 적용합니다. 올바른 출력 순서와, c를 지연하지 않고 현재 입력 c를 더했을 때 A에서 생길 수 있는 잘못된 결과를 구하세요.
Ler a explicação
올바른 결과는 A에서 -12+10=-2, B에서 10+100=110입니다. A의 곱이 2단계에 있을 때 현재 c가 B의 100이면 88이 나옵니다. valid만 맞게 지연해도 데이터 피연산자의 정렬이 틀리면 이 오류를 막지 못합니다.