Firmado Adición de dos vectores lógicos estándar al buscar desbordamiento y acarreo

1

Tengo lo que creo que es una implementación de trabajo para encontrar la suma de dos vectores firmados de 32 bits (std_logic_vector) en los que elegí expandir el resultado para tener siempre 33 bits a fin de preservar el bit de signo y poder Compruebe si se lleva a cabo con el bit expandido.

Mi método parece increíblemente sucio y me preguntaba si habría una forma más limpia de lograr mi objetivo, para futuras referencias.

sum <= std_logic_vector(resize(signed(std_logic_vector(signed(a_alu32) + signed(b_alu32))), 33));
c_alu32 <= sum(31);
--overflow--
if ((a_alu32(31)='0' and b_alu32(31)='0' and sum(31)='1') or (a_alu32(31)='1' and b_alu32(31)='1' and sum(31)='0')) then 
  ov_alu32<='1'; --logic to check for overflow
else
  ov_alu32<='0';
end if;

--removing the extra bit through concatenation to achieve my 32 bit sum
o_alu32 <= sum(32) & sum(30 downto 0);
    
pregunta MassDiffraction

2 respuestas

1

Su implementación no es correcta:

  • Debe realizar la extensión de signo antes de agregar a y b.
  • Una adición firmada no tiene indicador de acarreo, solo desbordamiento (se puede calcular pero no es válido); la adición sin firmar produce un indicador de acarreo pero no tiene un desbordamiento válido.
  • El bit de signo es, por definición, siempre se almacena en el bit más alto

Esto podría ser una reescritura más o menos agradable, que es más genérica. Solo depende de la longitud de a, byc. Por lo tanto, podría reutilizar este código para 16 o 64 bits, o lo que sea.

-- create locale signals with suffix '_s' for signed
-- both signals have one more bit than the original
signal a_alu32_s   : SIGNED(a_alu32'length downto 0);
signal b_alu32_s   : SIGNED(b_alu32'length downto 0);
signal sum_alu32_s : SIGNED(a_alu32'length downto 0);
signal temp        : std_logic_vector(2 downto 0);

-- convert type and perform a sign-extension
a_alu32_s <= resize(signed(a_alu32), a_alu32_s'length);
b_alu32_s <= resize(signed(b_alu32), b_alu32_s'length);

-- addition of two 33 bit values
sum_alu32_s <= a_alu32_s + b_alu32_s;

-- resize to require size and type conversion
o_alu32 <= std_logic_vector(resize(sum_alu32_s, o_alu32'length));

-- flag calculations
--c_alu32  <= sum_32_s(sum_alu32_s'high);

-- concat the three relevant sign-bits from a,b and sum to one vector
temp     <= a_alu32_s(a_alu32_s'high) & b_alu32_s(b_alu32_s'high) & sum_alu32_s(sum_alu32_s'high);
ov_alu32 <= (temp = "001") or (temp = "110");
    
respondido por el Paebbels
1

Esta respuesta considera la respuesta de Paebbels primero y luego da otro enfoque (correcto).

El OP tiene dos números de 32 bits que desea agregar. Pedir un número de 33 bits para poder detectar un desbordamiento. Como se usa 1 bit para indicar que "se ha desbordado - sí / no pregunta", el resultado es nuevamente un número de 32 bits. En otras palabras: número de 32 bits + indicador de desbordamiento de 1 bit = 33 bits. Que es conceptualmente diferente a un número de 33 bits (lo que sería un diseño extraño). También tenga en cuenta que sum(32) & sum(30 downto 0) son 32 bits (el resultado final).

Ahora considerando la respuesta de Paebbels: Supongamos que a_alu32 y b_alu32 tienen un signo de 2 bits, un bit para la cantidad (número absoluto), 1 bit para el signo. Luego redimensione a 3 bits (1 bit de signo, 2 bits de cantidad) para a_alu32_s y b_alu32_s. Ejemplo:

  • números de entrada: 01 y 01 (ambos con 1 en decimal)
  • extensión a 3 bits: 001 y 001
  • suma: 001 + 001 = 010
  • toma los bits más altos de a, by suma: 000
  • ¿ 000 es igual a 001 o 110 ? no ... por lo tanto no se ha desbordado (según la lógica de Paebbels)
  • Sin embargo, ¿qué hace Paebbels para obtener el resultado final de nuevo a 32 bits (y en este ejemplo, por lo tanto, 2 bits)? %código%. ¿Cómo es que o_alu32 <= std_logic_vector(resize(sum_alu32_s, o_alu32'length)); se redimensiona nuevamente a dos bits? Tome el bit de signo 010 , tome el resto 0 , elimine el msb del resto 10 , bit de signo de pegamento + resto-con-1 bit menos - > %código%. 10 -> 0 es 00 en firmado. Entonces 00 y no se produjo ningún desbordamiento. Extraño ... extraño.

La solución que esta respuesta propone es mirar los 2 bits más altos de la suma. Haciendo que sea un AND de dos vías en lugar de un AND de tres vías (también se guarda la lógica). Cuando el bit más alto de la parte de cantidad se ha "activado", se ha producido un desbordamiento (es decir, el número absoluto ha aumentado un bit adicional). "activo" puede ser 0 o 1 + 1 = 0 dependiendo del bit de signo. Ejemplo: 0 es un número positivo con en la parte de cantidad el bit más alto es "activo" ( 1 ), 010 es un número negativo con el bit de cantidad más alto "activo" ( 1 ) ( 101 (-3) es menor que 0 (-2) y menor que 101 (-1) en dos complementos).

Aquí hay una tabla donde:

  • in1 y in2 son los números de entrada
  • resized1 y resized2 y las versiones temporales redimensionadas
  • suma es la suma de las versiones redimensionadas
  • ov1 es si ha ocurrido un desbordamiento con el método de Paebbels
  • ov2 es si se ha producido un desbordamiento al observar los dos bits msb de la suma (bit de signo + msn de cantidad-parte) que debería ser 110 o 111

tabla:

╔═════╦═════╦══════════╦══════════╦════════════╦═════╦═════╗
║ in1 ║ in2 ║ resized1 ║ resized2 ║    sum     ║ ov1 ║ ov2 ║
╠═════╬═════╬══════════╬══════════╬════════════╬═════╬═════╣
║  00 ║  00 ║      000 ║      000 ║ 000        ║ no  ║ no  ║
║  00 ║  01 ║      000 ║      001 ║ 001        ║ no  ║ no  ║
║  00 ║  10 ║      000 ║      110 ║ 110        ║ no  ║ no  ║
║  00 ║  11 ║      000 ║      111 ║ 111        ║ no  ║ no  ║
║  01 ║  00 ║      001 ║      000 ║ 001        ║ no  ║ no  ║
║  01 ║  01 ║      001 ║      001 ║ 010        ║ no  ║ yes ║
║  01 ║  10 ║      001 ║      110 ║ 111        ║ no  ║ no  ║
║  01 ║  11 ║      001 ║      111 ║ 110        ║ no  ║ no  ║
║  10 ║  00 ║      110 ║      000 ║ 110        ║ no  ║ no  ║
║  10 ║  01 ║      110 ║      001 ║ 111        ║ no  ║ no  ║
║  10 ║  10 ║      110 ║      110 ║ 1100 (100) ║ no  ║ yes ║
║  10 ║  11 ║      110 ║      111 ║ 1101 (101) ║ no  ║ yes ║
║  11 ║  00 ║      111 ║      000 ║ 111        ║ no  ║ no  ║
║  11 ║  01 ║      111 ║      001 ║ 1000 (000) ║ no  ║ no  ║
║  11 ║  10 ║      111 ║      110 ║ 1101 (101) ║ no  ║ yes ║
║  11 ║  11 ║      111 ║      111 ║ 1110 (110) ║ no  ║ yes ║
╚═════╩═════╩══════════╩══════════╩════════════╩═════╩═════╝

Tenga en cuenta que la suma puede desbordarse, pero esto está bien porque solo nos preocupamos por el desbordamiento de los dos números originales que nos gustaría agregar. Este código provoca el desbordamiento de la suma 01 . En este ejemplo, al agregar 2 números de 3 bits se obtiene otro número de 3 bits y se pierde el msb, puede ver este efecto en la columna de suma.

Conclusión: quizás seamos yo y no entendí la solución de Paebbels. ¡Pero cuando ejecuto los números obtengo un resultado donde el método de Paebbels no detecta ningún desbordamiento!

    
respondido por el Flip

Lea otras preguntas en las etiquetas