54 / 63 · Conceito
Multiplicador unsigned multiciclo por deslocamento e soma
Distribua a acumulação de produtos parciais em W ciclos e verifique aceitação, conclusão, última soma, largura e invariantes.
As aulas podem ser lidas gratuitamente. Inscreva-se para salvar o progresso.
Pré-requisitos: circuitos sequenciais, atribuições não bloqueantesAtribuição não bloqueante Atribuição escrita com <= em RTL sequencial. Avalia o lado direito e agenda a atualização, permitindo que os registradores da mesma borda calculem a partir do estado anterior. Saiba mais, contadores, deslocamentos e somadores.
Reutilize um somador durante vários ciclos
A multiplicação unsignedunsigned Interpretação de uma sequência de bits como inteiro não negativo. Com n bits, o intervalo é de 0 a 2^n−1; pode diferir da interpretação signed dos mesmos bits. Saiba mais de W bits soma os produtos parciais escolhidos por cada bit de B:
Somá-los todos simultaneamente exige muita lógica. Aqui usamos um somador W vezes, trocando área por taxa de processamento. Um laço RTL não cria automaticamente um circuito multiciclo: são necessários registradoresRegistrador Circuito que armazena vários bits de estado. Os registradores síncronos deste curso capturam a entrada especificada na borda de clock. Saiba mais de estado entre clocks e uma condição de término.
O acumulador P e o multiplicando deslocado M têm 2W bits; o multiplicador Q tem W. Inicializam-se P=0, M=A estendido com zeros e Q=B. Em cada ciclo de trabalho, se Q[0]=1, soma-se M a P; depois M se desloca uma posição à esquerda e Q uma à direita.
Após W passos, Q=0 e P contém o produto completo. Bastam 2W bits: e as somas parciais unsigned de P não superam o resultado final.
Para A=13,B=11,W=4, os bits baixos de Q são 1,1,0,1. P percorre 0→13→39→39→143 e os M usados são 13,26,52,104. Mesmo com Q[0]=0 no terceiro passo, deslocamentos e contador precisam avançar.
Cada coluna mostra o estado após a captura das entradas ou um passo de cálculo. A primeira inicializa; as quatro seguintes calculam. Na terceira operação, apenas P é mantido e M,Q se deslocam.
Ver os dados da forma de onda
| Sinal | Forma de onda | Valores do barramento |
|---|---|---|
| borda | 23452 | captura → passo 1 → passo 2 → passo 3 → passo 4 |
| P depois | 234.5 | 0 → 13 → 39 → 143 |
| M depois | 23452 | 13 → 26 → 52 → 104 → 208 |
| Q depois | 23452 | 11 → 5 → 2 → 1 → 0 |
| done depois | 0...1 |
Defina aceitação e conclusão
A interface aceita uma solicitação numa borda de subidaBorda de subida Instante em que o clock passa de 0 para 1. É diferente do nível alto, que abrange todo o intervalo com CLK=1. Saiba mais com start=1 quando livre. Em t0, apenas captura entradas. Calcula W vezes de t1 até tW; product e done ficam válidos logo após tW. A latência é W períodos, embora contar as duas extremidades produza W+1 bordas.
Com busy=1, start é ignorado, inclusive na borda final, porque busy era 1 antes dela. A próxima aceitação pode ocorrer a partir de tW+1: o intervalo mínimo entre solicitações é W+1 períodos. Se start continuar em 1, reinicia na próxima borda livre; normalmente o transmissor gera um pulso de acordo com a aceitação.
module mul_iter #(parameter int W = 8) (
input logic clk, rst, start,
input logic [W-1:0] a, b,
output logic busy, done,
output logic [2*W-1:0] product
);
localparam int CW = (W <= 1) ? 1 : $clog2(W);
localparam logic [CW-1:0] LAST = CW'(W-1);
logic [CW-1:0] step;
logic [2*W-1:0] acc, m, next_acc;
logic [W-1:0] q;
assign next_acc = acc + (q[0] ? m : {2*W{1'b0}});
always_ff @(posedge clk) begin
if (rst) begin
busy <= 1'b0;
done <= 1'b0;
product <= '0;
acc <= '0;
m <= '0;
q <= '0;
step <= '0;
end else begin
done <= 1'b0;
if (!busy) begin
if (start) begin
busy <= 1'b1;
acc <= '0;
m <= {{W{1'b0}}, a};
q <= b;
step <= '0;
end
end else begin
acc <= next_acc;
m <= m << 1;
q <= q >> 1;
if (step == LAST) begin
product <= next_acc;
busy <= 1'b0;
done <= 1'b1;
end else begin
step <= step + 1'b1;
end
end
end
end
endmodulePressupõe-se W≥1, e CW é limitado a pelo menos um para evitar contador de zero bits com W=1. Reset é síncrono ativo em nível alto e cancela o trabalho em andamento. Mudar as entradas externas a,b após a aceitação não afeta o cálculo: são usados os valores armazenados m,q. product só muda com reset ou conclusão. done é um pulso de um ciclo, não um valid mantido até o consumo do resultado.
A atribuição final é product<=next_acc, não product<=acc. O lado direito não bloqueante lê o valor anterior; usar acc omitiria o produto parcial do último bit. Pelo mesmo motivo, escrever antes a atribuição de deslocamento de q não muda o uso de Q[0] atual por next_acc.
Invariante e decisões de implementação
Depois de k passos:
Separe Q em sua parte par e bit inferior para conferir que o próximo passo conserva a igualdade. Em k=W, Q=0 e P=AB. Esse invarianteInvariante Condição que deve ser verdadeira em toda execução permitida. Por exemplo, a ocupação de uma FIFO com profundidade 4 sempre fica entre 0 e 4. Saiba mais explica a ordem de acumulação e deslocamento melhor do que observar apenas uma onda pequena.
O caminho crítico de cada passo inclui somador de 2W bits e seleção. Remover o operador de multiplicação não garante menor área nem maior velocidade: compare blocos DSP de FPGA, síntese e taxaTaxa de processamento Quantidade de operações aceitas ou concluídas por unidade de tempo. Um pipeline pode aumentá-la sem reduzir a latência de uma operação individual. Saiba mais necessária. O módulo não implementa término antecipado, signed nem backpressure de resultados. O consumidor deve garantir que não perde done.
Teste 0,1,máximo e B com apenas seu bit superior ativo; este último revela a omissão da soma final. Teste também start e entradas mudando durante busy e cancelamento por reset.
Experimente
W=4,A=9,B=10 são aceitos em t0. Calcule acc,q,done após t1–t4 e indique a primeira borda possível para outra aceitação. O que product<=acc produziria ao terminar?
Ler a explicação
Inicialmente acc=0,m=9,q=1010. t1: bit baixo 0, acc=0,q=0101,done=0. t2: soma m=18, acc=18,q=0010,done=0. t3: bit baixo 0, acc=18,q=0001,done=0. t4: soma m=72, acc=90,q=0000,done=1,busy=0 e product=90. Antes de t4 busy=1, portanto não aceita start; t5 é a primeira borda possível. product<=acc leria o antigo acc=18 e omitiria o último produto parcial 72.