📄 mulxx.vhd
字号:
-- output of CoreGen module generator
-- $Header: mulVHT.vhd,v 1.4 1998/06/15 16:35:04 tonyw Exp $
-- ************************************************************************
-- Copyright 1996-1998 - Xilinx, Inc.
-- All rights reserved.
-- ************************************************************************
--
-- Description:
-- Variable operand multiplier
--
library IEEE;
use IEEE.STD_LOGIC_1164.all;
library xul;
use xul.ul_utils.all;
entity mulxx is
port( a : in std_logic_vector( 16 - 1 downto 0 );
b : in std_logic_vector( 16 - 1 downto 0 );
c : in std_logic;
ce : in std_logic;
prod : out std_logic_vector( (16 + 16 -1) downto 0));
end mulxx;
architecture behv of mulxx is
constant aw : integer := 16;
constant bw : integer := 16;
constant signed : boolean := true;
function level_nums(n: integer) return integer is
begin
case n is
when 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 => return 4;
when 5 | 6 | 7 | 8 => return 3;
when 3 | 4 => return 2;
when 1 | 2 => return 1;
when others => assert (false)
report "The function level_nums recd an invalid param " & int_2_string(n)
severity error;
return 0;
end case;
end level_nums;
function convert_abs_2_two_comp(vect : std_logic_vector)
return std_logic_vector is
variable local_vect : std_logic_vector(vect'HIGH downto 0);
begin
-- ones complement first
for i in 0 to vect'high loop
if (vect(i) = '0') then
local_vect(i) := '1';
else
local_vect(i) := '0';
end if;
end loop;
-- add 1 and carry to next hight bit
for i in 0 to vect'high loop
if (local_vect(i) = '0') then
local_vect(i) := '1';
exit;
else
local_vect(i) := '0';
end if;
end loop;
return local_vect;
end convert_abs_2_two_comp ;
type data_array is array(level_nums((bw+1)/2) +1 downto 0) of
std_logic_vector(aw+bw -1 downto 0);
begin
process
variable setup : boolean := TRUE;
variable va : std_logic_vector( aw - 1 downto 0 );
variable vb : std_logic_vector( bw - 1 downto 0 );
variable vprod : std_logic_vector( aw+bw - 1 downto 0 );
variable cin : std_logic;
variable value : std_logic;
variable s : data_array;
variable negative : boolean;
variable i,j : integer;
variable a_value : integer;
variable b_value : integer;
variable prod_value : integer;
variable index : integer;
variable clk_cycles : integer;
begin
clk_cycles := level_nums((bw+1)/2) + 2 ;
if (setup = TRUE) then
for i in clk_cycles-1 downto 0 loop
s(i) := setall0(aw+bw);
end loop;
setup := FALSE;
elsif (rat(c) = 'X' AND rat(ce) /= '0' AND rat(c'LAST_VALUE)/='X') then
for i in clk_cycles-1 downto 0 loop
s(i) := setallX(aw+bw);
end loop;
elsif (c'event and rat(c)='1' and rat(c'last_value)='0') then
if (rat(ce)='X') then
vprod := setallX(aw+bw);
elsif (rat(ce)='1') then
if (anyX(a) or anyX(b)) then
vprod := setallX(aw+bw);
else
negative := FALSE;
va := std_logic_vector_2_var(a);
vb := std_logic_vector_2_var(b);
if (signed) then
if ( (va(aw-1) xor vb(bw-1)) = '1' ) then
negative := TRUE;
end if ;
if (va(aw-1) = '1') then
va := two_comp(va);
end if ;
if (vb(bw-1) = '1') then
vb := two_comp(vb);
end if ;
end if;
vprod := setall0(aw+bw);
if ( aw + bw < 32 ) then
a_value := std_logic_vector_2_posint(va);
b_value := std_logic_vector_2_posint(vb);
prod_value := a_value * b_value;
vprod := int_2_std_logic_vector(prod_value,aw+bw);
else
for i in 0 to bw -1 loop -- bw width
if (vb(i) = '1') then
index := i;
cin := '0';
for j in 0 to aw-1 loop -- add a to prod
value := vprod(index) xor va(j) xor cin; -- sum
cin := (vprod(index) and va(j)) or (vprod(index) and cin) or
(va(j) and cin); -- carry
vprod(index) := value;
index := index + 1;
end loop;
vprod(index) := vprod(index) xor cin; -- last carry
else
cin := '0';
end if;
end loop;
end if;
if (negative) then
vprod := convert_abs_2_two_comp(vprod);
end if;
end if;
end if;
for i in clk_cycles-2 downto 0 loop
s(i+1) := s(i);
end loop;
s(0) := vprod;
end if;
prod <= s(clk_cycles-1);
wait on c;
end process;
end behv;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -