Partiamo dalla definizione del tipo UNSIGNED:
- Code: Select all
type UNSIGNED is array (NATURAL range <>) of STD_LOGIC;
Come si può notare è un array di STD_LOGIC quindi supporta intrinsecamente il tipo indefinito (ovvero 'X')
L'operatore somma in caso di valori contententi 'X' restituisce però un valore completamente non definito come è possibile dedurre dalla sua implementazione
- Code: Select all
function "+" (L, R: UNSIGNED) return UNSIGNED is
constant SIZE: NATURAL := MAX(L'LENGTH, R'LENGTH);
variable L01 : UNSIGNED(SIZE-1 downto 0);
variable R01 : UNSIGNED(SIZE-1 downto 0);
-- Synthesis directives :
attribute SYNTHESIS_RETURN of L01:variable is "ADD" ;
begin
if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAU;
end if;
L01 := TO_01(RESIZE(L, SIZE), 'X');
if (L01(L01'LEFT)='X') then return L01;
end if;
R01 := TO_01(RESIZE(R, SIZE), 'X');
if (R01(R01'LEFT)='X') then return R01;
end if;
return ADD_UNSIGNED(L01, R01, '0');
end "+";
"Bypassando" i vari controlli è possibile utilizzare direttamente la funzione ADD_UNSIGNED così definita inserendola all'interno del proprio codice in quanto non dichiarata dall'interfaccia del package numeric_std.
- Code: Select all
-- this internal function computes the addition of two UNSIGNED
-- with input CARRY
-- * the two arguments are of the same length
function ADD_UNSIGNED (L, R: UNSIGNED; C: STD_LOGIC) return UNSIGNED is
constant L_LEFT: INTEGER := L'LENGTH-1;
alias XL: UNSIGNED(L_LEFT downto 0) is L;
alias XR: UNSIGNED(L_LEFT downto 0) is R;
variable RESULT: UNSIGNED(L_LEFT downto 0);
variable CBIT: STD_LOGIC := C;
begin
for I in 0 to L_LEFT loop
RESULT(I) := CBIT xor XL(I) xor XR(I);
CBIT := (CBIT and XL(I)) or (CBIT and XR(I)) or (XL(I) and XR(I));
end loop;
return RESULT;
end ADD_UNSIGNED;
Tale funzione ritorna correttamente 1XX1 nella somma 1X01+00X0
Leonardo