📄 std_logic_class.bdy
字号:
carry := '1';
for i in 0 to y_1sC'length-1 loop
y(i) := y_1sC(i) xor carry;
carry := y_1sC(i) and carry;
end loop;
else
y := product;
end if;
return y;
end "*";
function "/" ( -- 29.11.92
a, b: twos_complement
) return twos_complement is
constant y_length: integer := a'length + b'length;
constant a_extended_length: integer := b'length-1;
variable y_sign: std_ulogic;
variable a_1sC, a_abs: twos_complement(a'length-1 downto 0);
variable b_1sC, b_abs: twos_complement(b'length-1 downto 0);
variable carry: std_ulogic;
variable a_extended: twos_complement(a_extended_length-1 downto 0);
variable dividend_match: twos_complement(b'length-1 downto 0);
variable quotient: twos_complement(a'length-1 downto 0);
variable remainder: twos_complement(b'length-1 downto 0);
variable quotient_abs, quotient_1sC: twos_complement(a'length-1 downto 0);
variable remainder_abs, remainder_1sC: twos_complement(b'length-1 downto 0);
variable y: twos_complement(y_length-1 downto 0);
begin
-- firstly, the sign of the result is extracted
y_sign := a(a'length-1) xor b(b'length-1);
-- second, the operands are converted to absolute values
if (a(a'length-1) = '1') then
a_1sC := not a;
carry := '1';
for i in 0 to a'length-1 loop
a_abs(i) := a_1sC(i) xor carry;
carry := a_1sC(i) and carry;
end loop;
else
a_abs := a;
end if;
if (b(b'length-1) = '1') then
b_1sC := not b;
carry := '1';
for i in 0 to b'length-1 loop
b_abs(i) := b_1sC(i) xor carry;
carry := b_1sC(i) and carry;
end loop;
else
b_abs := b;
end if;
-- thirdly, the division of the absolute values takes place
for i in a_extended_length-1 downto 0 loop
a_extended(i) := '0';
end loop;
dividend_match(b_abs'length-1 downto 1) := a_extended;
for i in a_abs'length-1 downto 0 loop
dividend_match := dividend_match(b_abs'length-1 downto 1) & a_abs(i);
if (b_abs <= dividend_match) then
dividend_match := dividend_match - b_abs;
quotient_abs(i) := '1';
else
quotient_abs(i) := '0';
end if;
end loop;
remainder_abs := dividend_match;
-- now the result's absolute value is converted to it's 2's complement value
-- note that the sign of the remainder follows the sign of the dividend
if (y_sign = '1') then
quotient_1sC := not quotient_abs;
carry := '1';
for i in 0 to quotient_1sC'length-1 loop
quotient(i) := quotient_1sC(i) xor carry;
carry := quotient_1sC(i) and carry;
end loop;
else
quotient := quotient_abs;
end if;
if (a(a'length-1) = '1') then
remainder_1sC := not remainder_abs;
carry := '1';
for i in 0 to remainder_1sC'length-1 loop
remainder(i) := remainder_1sC(i) xor carry;
carry := remainder_1sC(i) and carry;
end loop;
else
remainder := remainder_abs;
end if;
y := quotient & remainder;
return y;
end "/";
function "mod" ( -- 2.12.92
a, b: twos_complement
) return twos_complement is
constant y_length: integer := a'length + b'length;
constant a_extended_length: integer := b'length-1;
variable a_1sC, a_abs: twos_complement(a'length-1 downto 0);
variable b_1sC, b_abs: twos_complement(b'length-1 downto 0);
variable carry: std_ulogic;
variable a_extended: twos_complement(a_extended_length-1 downto 0);
variable dividend_match: twos_complement(b'length-1 downto 0);
variable remainder: twos_complement(b'length-1 downto 0);
variable remainder_abs, remainder_1sC: twos_complement(b'length-1 downto 0);
variable y: twos_complement(b'length-1 downto 0);
begin
-- firstly, the operands are converted to absolute values
if (a(a'length-1) = '1') then
a_1sC := not a;
carry := '1';
for i in 0 to a'length-1 loop
a_abs(i) := a_1sC(i) xor carry;
carry := a_1sC(i) and carry;
end loop;
else
a_abs := a;
end if;
if (b(b'length-1) = '1') then
b_1sC := not b;
carry := '1';
for i in 0 to b'length-1 loop
b_abs(i) := b_1sC(i) xor carry;
carry := b_1sC(i) and carry;
end loop;
else
b_abs := b;
end if;
-- secondly, the division of the absolute values takes place
for i in a_extended_length-1 downto 0 loop
a_extended(i) := '0';
end loop;
dividend_match(b_abs'length-1 downto 1) := a_extended;
for i in a_abs'length-1 downto 0 loop
dividend_match := dividend_match(b_abs'length-1 downto 1) & a_abs(i);
if (b_abs <= dividend_match) then
dividend_match := dividend_match - b_abs;
end if;
end loop;
remainder_abs := dividend_match;
-- now the result's absolute value is converted to it's 2's complement value
-- note that the sign of the remainder follows the sign of the dividend
if (a(a'length-1) = '1') then
remainder_1sC := not remainder_abs;
carry := '1';
for i in 0 to remainder_1sC'length-1 loop
remainder(i) := remainder_1sC(i) xor carry;
carry := remainder_1sC(i) and carry;
end loop;
else
remainder := remainder_abs;
end if;
y := remainder;
return y;
end "mod";
function "rem" ( -- 2.12.92
a, b: twos_complement
) return twos_complement is
constant y_length: integer := a'length + b'length;
constant a_extended_length: integer := b'length-1;
variable a_1sC, a_abs: twos_complement(a'length-1 downto 0);
variable b_1sC, b_abs: twos_complement(b'length-1 downto 0);
variable carry: std_ulogic;
variable a_extended: twos_complement(a_extended_length-1 downto 0);
variable dividend_match: twos_complement(b'length-1 downto 0);
variable remainder: twos_complement(b'length-1 downto 0);
variable remainder_abs, remainder_1sC: twos_complement(b'length-1 downto 0);
variable y: twos_complement(b'length-1 downto 0);
begin
-- firstly, the operands are converted to absolute values
if (a(a'length-1) = '1') then
a_1sC := not a;
carry := '1';
for i in 0 to a'length-1 loop
a_abs(i) := a_1sC(i) xor carry;
carry := a_1sC(i) and carry;
end loop;
else
a_abs := a;
end if;
if (b(b'length-1) = '1') then
b_1sC := not b;
carry := '1';
for i in 0 to b'length-1 loop
b_abs(i) := b_1sC(i) xor carry;
carry := b_1sC(i) and carry;
end loop;
else
b_abs := b;
end if;
-- secondly, the division of the absolute values takes place
for i in a_extended_length-1 downto 0 loop
a_extended(i) := '0';
end loop;
dividend_match(b_abs'length-1 downto 1) := a_extended;
for i in a_abs'length-1 downto 0 loop
dividend_match := dividend_match(b_abs'length-1 downto 1) & a_abs(i);
if (b_abs <= dividend_match) then
dividend_match := dividend_match - b_abs;
end if;
end loop;
remainder_abs := dividend_match;
-- now the result's absolute value is converted to it's 2's complement value
-- note that the sign of the remainder follows the sign of the dividend
if (a(a'length-1) = '1') then
remainder_1sC := not remainder_abs;
carry := '1';
for i in 0 to remainder_1sC'length-1 loop
remainder(i) := remainder_1sC(i) xor carry;
carry := remainder_1sC(i) and carry;
end loop;
else
remainder := remainder_abs;
end if;
y := remainder;
return y;
end "rem";
function "**" ( -- 2.12.92
a, b: twos_complement
) return twos_complement is
variable y: twos_complement(a'length-1 downto 0);
begin
assert false
report "Error 0001." &
"Library = vfp." &
"Package Body = twos_complement_operators." &
"Function = **." &
"The function (twos_complement) ** (twos_complement) is not supported." &
"However, to_twos_complement(to_integer(twos_complementy) ** to_integer(twos_complement)) is supported."
-- See the to_integer and the to_twos_complement conversion functions
severity error;
y := a;
return y;
end "**";
function "abs" ( -- 2.12.92
a: twos_complement
) return twos_complement is
-- the function abs_wordlength returns a'length+1 if a is
-- -2(N-1) otherwise it returns a'length
constant y_length: integer := abs_wordlength(a);
variable a_1sC: twos_complement(a'length-1 downto 0);
variable carry: std_ulogic;
variable y: twos_complement(y_length-1 downto 0);
begin
if (y_length = a'length+1) then
y(a'length) := '1';
end if;
if (a(a'length-1) = '1') then
a_1sC := not a;
carry := '1';
for i in 0 to a'length-1 loop
y(i) := a_1sC(i) xor carry;
carry := a_1sC(i) and carry;
end loop;
else
y := a;
end if;
return y;
end "abs";
function "+" ( -- 2.12.92
a: twos_complement
) return twos_complement is
variable y: twos_complement(a'length-1 downto 0);
begin
assert false
report "Warning 0001." &
"Library = vfp." &
"Package Body = twos_complement_operators." &
"Function = +." &
"The function + (twos_complement) is defined as ... " &
" <return_value> := <actual_parameter> " &
"Thus there is no point in taking the positive value of a twos_complement object."
severity warning;
y := a;
return y;
end "+";
function "-" ( -- 2.12.92
a: twos_complement
) return twos_complement is
-- the function abs_wordlength returns a'length+1 if a is
-- -2(N-1) otherwise it returns a'length
constant y_length: integer := abs_wordlength(a);
variable a_1sC: twos_complement(a'length-1 downto 0);
variable carry: std_ulogic;
variable y: twos_complement(y_length-1 downto 0);
begin
if (y_length = a'length+1) then
y(a'length) := '0';
end if;
a_1sC := not a;
carry := '1';
for i in 0 to a'length-1 loop
y(i) := a_1sC(i) xor carry;
carry := a_1sC(i) and carry;
end loop;
return y;
end "-";
-- shift operators
-- general purpose functions
function longest ( -- 25.11.92
a, b: twos_complement
) return integer is
variable y: integer;
begin
if (a'length >= b'length) then
y := a'length;
else
y := b'length;
end if;
return y;
end longest;
function abs_wordlength (
a: twos_complement
) return integer is
variable any_1s: std_ulogic;
variable y: integer;
begin
any_1s := '0';
-- all bits excpet the MSB are tested for being 1
-- if none are 1, all bits are 0, and any_1s is 0
-- hence either 0 or -2(N-1) has been found
-- if this function is only called when a is -ve
-- it finds if a is -2(N-1)
for i in 0 to a'length-2 loop -- unary OR operation
any_1s := a(i) or any_1s;
end loop;
if ((a(a'length-1) = '1') and (any_1s = '0')) then
y := a'length + 1;
else
y := a'length;
end if;
return y;
end abs_wordlength;
-- hardware functions
-- none yet defined
-- mathematical functions
-- none yet defined
end std_logic_class;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -