54 / 63 · Concepto
Multiplicador unsigned multiciclo por desplazamiento y suma
Reparta la acumulación de productos parciales en W ciclos y verifique aceptación, finalización, última suma, ancho e invariantes.
Las lecciones se pueden leer gratis. Inscríbete para guardar el progreso.
Requisitos previos: circuitos secuenciales, asignaciones no bloqueantesAsignación no bloqueante Asignación escrita con <= en RTL secuencial. Evalúa el lado derecho y programa la actualización, permitiendo que los registros del mismo flanco calculen a partir del estado anterior. Más información, contadores, desplazamientos y sumadores.
Reutilice un sumador durante varios ciclos
La multiplicación unsignedunsigned Interpretación de una secuencia de bits como entero no negativo. Con n bits, el rango es de 0 a 2^n−1; puede diferir de la interpretación signed de los mismos bits. Más información de W bits suma los productos parciales elegidos por cada bit de B:
Sumarlos todos a la vez necesita mucha lógica. Aquí usamos un sumador W veces, intercambiando área por tasa de procesamiento. Un bucle RTL no crea automáticamente un circuito multiciclo: hacen falta registrosRegistro Circuito que almacena varios bits de estado. Los registros síncronos de este curso capturan la entrada especificada en el flanco de reloj. Más información de estado entre relojes y una condición de fin.
El acumulador P y el multiplicando desplazado M tienen 2W bits; el multiplicador Q tiene W. Se inicia P=0, M=A extendido con ceros y Q=B. En cada ciclo de trabajo, si Q[0]=1 se suma M a P; después M se desplaza una posición a la izquierda y Q una a la derecha.
Tras W pasos, Q=0 y P contiene el producto completo. Bastan 2W bits: y las sumas parciales unsigned de P no superan el resultado final.
Para A=13,B=11,W=4, los bits bajos de Q son 1,1,0,1. P recorre 0→13→39→39→143 y los M usados son 13,26,52,104. Aunque Q[0]=0 en el tercer paso, deben avanzar los desplazamientos y el contador.
Cada columna muestra el estado posterior a la captura o a un paso de cálculo. La primera inicializa; las cuatro siguientes calculan. En la tercera operación solo P se conserva y M,Q se desplazan.
Ver los datos de la forma de onda
| Señal | Forma de onda | Valores del bus |
|---|---|---|
| flanco | 23452 | captura → paso 1 → paso 2 → paso 3 → paso 4 |
| P después | 234.5 | 0 → 13 → 39 → 143 |
| M después | 23452 | 13 → 26 → 52 → 104 → 208 |
| Q después | 23452 | 11 → 5 → 2 → 1 → 0 |
| done después | 0...1 |
Defina aceptación y finalización
La interfaz acepta una petición en un flanco ascendenteFlanco ascendente Instante en que el reloj pasa de 0 a 1. Se distingue del nivel alto, que abarca todo el intervalo con CLK=1. Más información con start=1 estando libre. En t0 solo captura entradas. Calcula W veces desde t1 hasta tW; product y done son válidos justo después de tW. La latencia es W periodos, aunque contando ambos extremos aparecen W+1 flancos.
Con busy=1 se ignora start, incluso en el flanco final porque busy era 1 antes de él. La próxima aceptación más temprana es tW+1: el intervalo mínimo entre peticiones es W+1 periodos. Si start sigue en 1, se reinicia al próximo flanco libre; normalmente el emisor genera un pulso acorde con la aceptación.
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
endmoduleSe supone W≥1 y CW se limita a uno como mínimo para evitar un contador de cero bits con W=1. Reset es síncrono activo en alto y cancela el trabajo en curso. Cambiar a,b externos tras aceptar no afecta: se usan m,q almacenados. product solo cambia con reset o finalización. done es un pulso de un ciclo, no un valid conservado hasta consumir el resultado.
La asignación final es product<=next_acc, no product<=acc. El lado derecho no bloqueante lee el valor previo; usar acc omitiría el producto parcial del último bit. Por lo mismo, escribir antes la asignación de desplazamiento de q no cambia que next_acc use Q[0] actual.
Invariante y decisiones de implementación
Después de k pasos:
Separe Q en su parte par y bit inferior para comprobar que el siguiente paso conserva la igualdad. En k=W, Q=0 y P=AB. Este invarianteInvariante Condición que debe cumplirse en toda ejecución permitida. Por ejemplo, la ocupación de una FIFO de profundidad 4 siempre está entre 0 y 4. Más información explica el orden de acumulación y desplazamiento mejor que observar solo una onda pequeña.
El camino crítico de cada paso incluye sumador de 2W bits y selección. Quitar el operador de multiplicación no garantiza menor área ni mayor velocidad: compare bloques DSP de FPGA, síntesis y tasaTasa de procesamiento Número de operaciones aceptadas o completadas por unidad de tiempo. Un pipeline puede aumentarla sin reducir la latencia de una operación individual. Más información requerida. El módulo no implementa salida anticipada, signed ni contrapresión de resultados. El consumidor debe garantizar que no pierde done.
Pruebe 0,1,máximo y B con solo su bit superior activo; este último descubre la omisión de la suma final. Pruebe también los cambios de start y de las entradas durante busy y la cancelación por reset.
Inténtalo tú
Se acepta W=4,A=9,B=10 en t0. Calcule acc,q,done después de t1–t4 e indique el primer flanco posible para otra aceptación. ¿Qué produciría product<=acc al terminar?
Leer la explicación
Inicialmente acc=0,m=9,q=1010. t1: bit bajo 0, acc=0,q=0101,done=0. t2: suma m=18, acc=18,q=0010,done=0. t3: bit bajo 0, acc=18,q=0001,done=0. t4: suma m=72, acc=90,q=0000,done=1,busy=0 y product=90. Antes de t4 busy=1, así que no acepta start; t5 es el primer flanco posible. product<=acc leería el antiguo acc=18 y omitiría el último producto parcial 72.