📄 std_logic_class.bdy
字号:
a, b: std_logic_vector
) 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;
-- hardware functions
function posedge (
signal a: std_ulogic
) return boolean is
variable y: boolean;
begin
if (a = '1') and a'event then
y := true;
else
y := false;
end if;
return y;
end posedge;
function negedge (
signal a: std_ulogic
) return boolean is
variable y: boolean;
begin
if (a = '0') and a'event then
y := true;
else
y := false;
end if;
return y;
end negedge;
-- mathematical functions
function log_2 (a: std_ulogic_vector) return integer is -- 15.11.95
variable index : integer;
begin
index := a'length - 1;
while index > -1 loop
if a(index) = '1' then
return index;
index := -1; -- required in order to exit the loop
else
index := index - 1;
if index = -1 then -- catches the case when a has no '1's in it
assert FALSE
report "log_2(a) returns an out-of-range value"
severity warning;
return integer'low; -- a stupid value => a 2**32-bit vector
-- with an LSB of 1 !!!
end if;
end if;
-- if a >= 1, index goes to -1 in order to exit the loop after returning index=0
-- if a = 0, index goes to -1, return value = -integer'low
-- if a is not bit_vector pattern, (i.e., contains non-0,1 values)
-- the U,X,W,H,L,Z,- are also treated as 0
end loop;
end log_2;
-- (ii)
-- arithmetic array type definitions
-- std_ulogic is defined in std_logic_1164
-- arithmetic arrays of std_logic are defined in IEEE.numeric_std
-- twos_complement functions
-- logical operators
function "not" ( -- 25.11.92
a: twos_complement
) return twos_complement is
variable yi: twos_complement(a'length-1 downto 0);
begin
for i in 0 to a'length-1 loop
yi(i) := not (a(i));
end loop;
return yi;
end "not";
function "and" ( -- 24.11.92
a, b: twos_complement
) return twos_complement is
variable y: twos_complement(a'length-1 downto 0);
begin
if (a'length /= b'length) then
assert false
report "Error 0000." &
"Library = vfp." &
"Package Body = twos_complement_operators." &
"Function = and." &
"The wordlength of a and b MUST be the same."
severity error;
else
for i in 0 to a'length-1 loop
y(i) := a(i) and b(i);
end loop;
end if;
return y;
end "and";
function "or" ( -- 25.11.92
a, b: twos_complement
) return twos_complement is
variable y: twos_complement(a'length-1 downto 0);
begin
if (a'length /= b'length) then
assert false
report "Error 0001." &
"Library = vfp." &
"Package Body = twos_complement_operators." &
"Function = or." &
"The wordlength of a and b MUST be the same."
severity error;
else
for i in 0 to a'length-1 loop
y(i) := a(i) or b(i);
end loop;
end if;
return y;
end "or";
function "xor" ( -- 25.11.92
a, b: twos_complement
) return twos_complement is
variable y: twos_complement(a'length-1 downto 0);
begin
if (a'length /= b'length) then
assert false
report "Error 0001." &
"Library = vfp." &
"Package Body = twos_complement_operators." &
"Function = xor." &
"The wordlength of a and b MUST be the same."
severity error;
else
for i in 0 to a'length-1 loop
y(i) := a(i) xor b(i);
end loop;
end if;
return y;
end "xor";
function "nand" ( -- 25.11.92
a, b: twos_complement
) return twos_complement is
variable y: twos_complement(a'length-1 downto 0);
begin
if (a'length /= b'length) then
assert false
report "Error 0001." &
"Library = vfp." &
"Package Body = twos_complement_operators." &
"Function = nand." &
"The wordlength of a and b MUST be the same."
severity error;
else
for i in 0 to a'length-1 loop
y(i) := a(i) nand b(i);
end loop;
end if;
return y;
end "nand";
function "nor" ( -- 25.11.92
a, b: twos_complement
) return twos_complement is
variable y: twos_complement(a'length-1 downto 0);
begin
if (a'length /= b'length) then
assert false
report "Error 0001." &
"Library = vfp." &
"Package Body = twos_complement_operators." &
"Function = nor." &
"The wordlength of a and b MUST be the same."
severity error;
else
for i in 0 to a'length-1 loop
y(i) := a(i) nor b(i);
end loop;
end if;
return y;
end "nor";
-- function "xnor" ( -- 25.11.92
-- a, b: twos_complement
-- ) return twos_complement is
-- variable y: twos_complement(a'length-1 downto 0);
-- begin
-- if (a'length /= b'length) then
-- assert false
-- report "Error 0001." &
-- "Library = vfp." &
-- "Package Body = twos_complement_operators." &
-- "Function = xnor." &
-- "The wordlength of a and b MUST be the same."
-- severity error;
-- else
-- for i in 0 to a'length-1 loop
-- y(i) := a(i) xnor b(i);
-- end loop;
-- end if;
-- return y;
-- end "xnor";
-- arithmetic operators
-- std_logic_class."+"(twos_complement, twos_complement) -> twos_complement
function "+" ( -- 25.11.92
a, b: twos_complement
) return twos_complement is
constant y_length: integer := longest (a, b);
variable a_sign_extended, b_sign_extended: twos_complement(y_length-1 downto 0);
variable y: twos_complement(y_length-1 downto 0);
variable carry: std_ulogic;
begin
carry := '0';
if (a'length < b'length) then
for i in b'length-1 downto a'length loop
a_sign_extended(i) := a(a'length-1);
end loop;
a_sign_extended(a'length-1 downto 0) := a;
for i in 0 to b'length-1 loop
y(i) := a_sign_extended(i) xor b(i) xor carry;
carry := (a_sign_extended(i) and b(i)) or
(a_sign_extended(i) and carry) or
(b(i) and carry);
end loop;
elsif (a'length > b'length) then
for i in a'length-1 downto b'length loop
b_sign_extended(i) := b(b'length-1);
end loop;
b_sign_extended(b'length-1 downto 0) := b;
for i in 0 to a'length-1 loop
y(i) := a(i) xor b_sign_extended(i) xor carry;
carry := (a(i) and b_sign_extended(i)) or
(a(i) and carry) or
(b_sign_extended(i) and carry);
end loop;
else -- i.e., (a'length = b'length)
for i in 0 to a'length-1 loop
y(i) := a(i) xor b(i) xor carry;
carry := (a(i) and b(i)) or
(a(i) and carry) or
(b(i) and carry);
end loop;
end if;
return y;
end "+";
function "-" ( -- 29.11.92
a, b: twos_complement
) return twos_complement is
constant y_length: integer := longest (a, b);
variable a_sign_extended, b_sign_extended: twos_complement(y_length-1 downto 0);
variable y: twos_complement(y_length-1 downto 0);
variable carry: std_ulogic;
begin
carry := '1';
if (a'length < b'length) then
for i in b'length-1 downto a'length loop
a_sign_extended(i) := a(a'length-1);
end loop;
a_sign_extended(a'length-1 downto 0) := a;
for i in 0 to b'length-1 loop
y(i) := a_sign_extended(i) xor (not b(i)) xor carry;
carry := (a_sign_extended(i) and (not b(i))) or
(a_sign_extended(i) and carry) or
(not (b(i)) and carry);
end loop;
elsif (a'length > b'length) then
for i in a'length-1 downto b'length loop
b_sign_extended(i) := b(b'length-1);
end loop;
b_sign_extended(b'length-1 downto 0) := b;
for i in 0 to a'length-1 loop
y(i) := a(i) xor (not b_sign_extended(i)) xor carry;
carry := (a(i) and (not b_sign_extended(i))) or
(a(i) and carry) or
((not b_sign_extended(i)) and carry);
end loop;
else -- i.e., (a'length = b'length)
for i in 0 to a'length-1 loop
y(i) := a(i) xor (not b(i)) xor carry;
carry := (a(i) and (not b(i))) or
(a(i) and carry) or
((not b(i)) and carry);
end loop;
end if;
return y;
end "-";
function "*" ( -- 30.11.92
a, b: twos_complement
) return twos_complement is
constant y_length: integer := a'length + b'length;
variable y_sign: std_ulogic;
variable a_1sC, multiplicand: twos_complement(a'length-1 downto 0);
variable b_1sC, multiplier: twos_complement(b'length-1 downto 0);
variable carry: std_ulogic;
variable partial_product: twos_complement(a'length-1 downto 0);
variable product_lsb: twos_complement(b'length-1 downto 0);
variable product: twos_complement(y_length-1 downto 0);
variable y_1sC: twos_complement(y_length-1 downto 0);
variable y: twos_complement(y_length-1 downto 0);
begin
-- firstly, the sign of the result is extracted -- BB x 02
y_sign := a(a'length-1) xor b(b'length-1); -- 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
multiplicand(i) := a_1sC(i) xor carry;
carry := a_1sC(i) and carry;
end loop;
else
multiplicand := 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
multiplier(i) := b_1sC(i) xor carry;
carry := b_1sC(i) and carry;
end loop;
else
multiplier := b;
end if; --
-- thirdly, the multiplication of the absolute values takes place
for i in 0 to (multiplicand'length - 1) loop
partial_product(i) := '0';
end loop;
for i in 0 to multiplier'length-1 loop
if (multiplier(i) = '1') then
partial_product := partial_product + multiplicand; --
product_lsb(i) := partial_product(0);
partial_product := '0' & partial_product(a'length-1 downto 1);
else
product_lsb(i) := partial_product(0);
partial_product := '0' & partial_product(a'length-1 downto 1);
end if;
end loop;
-- now the result's absolute value is converted to it's 2's complement value
product := partial_product & product_lsb; -- if all variables were 2scomp, there'd be no problem
if (y_sign = '1') then
y_1sC := not product;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -