altera_mf_87.vhd
来自「一个非常好的dc使用书籍 一个非常好的dc使用书籍」· VHDL 代码 · 共 1,443 行 · 第 1/5 页
VHD
1,443 行
sign_aclr_b : string := "ACLR3";
sign_pipeline_reg_b : string := "CLOCK0";
sign_pipeline_aclr_b : string := "ACLR3";
multiplier_reg : string := "CLOCK0";
multiplier_aclr : string := "ACLR3";
output_reg : string := "CLOCK0";
output_aclr : string := "ACLR3";
extra_multiplier_latency : integer := 0;
extra_accumulator_latency : integer := 0;
dedicated_multiplier_circuitry : string := "AUTO";
dsp_block_balancing : string := "AUTO";
lpm_hint : string := "UNUSED";
lpm_type : string := "altmult_accum"
);
port (
-- ----------------
-- PORT DECLARATION
-- ----------------
-- input data ports
dataa : in std_logic_vector(width_a -1 downto 0);
datab : in std_logic_vector(width_b -1 downto 0);
-- control signals
addnsub : in std_logic := 'Z';
accum_sload : in std_logic := '0';
signa : in std_logic := 'Z';
signb : in std_logic := 'Z';
-- clock ports
clock0 : in std_logic := '1';
clock1 : in std_logic := '1';
clock2 : in std_logic := '1';
clock3 : in std_logic := '1';
-- clock enable ports
ena0 : in std_logic := '1';
ena1 : in std_logic := '1';
ena2 : in std_logic := '1';
ena3 : in std_logic := '1';
-- clear ports
aclr0 : in std_logic := '0';
aclr1 : in std_logic := '0';
aclr2 : in std_logic := '0';
aclr3 : in std_logic := '0';
-- output ports
result : out std_logic_vector(width_result -1 downto 0) := (others => '0');
overflow : out std_logic :='0';
scanouta : out std_logic_vector (width_a -1 downto 0) := (others => '0');
scanoutb : out std_logic_vector (width_b -1 downto 0) := (others => '0')
);
end altmult_accum;
architecture behaviour of altmult_accum is
-- -------------------------------------
-- INTERNAL TEMPLATE DECLARATION
-- -------------------------------------
type pipeline_accum is array (extra_accumulator_latency downto 0) of std_logic_vector (width_result downto 0);
type pipeline_multi is array (extra_multiplier_latency downto 0) of std_logic_vector (width_a + width_b + 4 downto 0);
-- -------------------------------------
-- INTERNAL SIGNALS AND TYPE DECLARATION
-- -------------------------------------
signal temp_sum : std_logic_vector (width_result + 1 downto 0):= (others => '0');
signal mult_a : std_logic_vector (width_a -1 downto 0):= (others => '0');
signal mult_b : std_logic_vector (width_b -1 downto 0):= (others => '0');
signal mult_res : std_logic_vector (width_a + width_b -1 downto 0):= (others => '0');
signal acc_sload_reg : std_logic := '0';
signal accum_sload_pipe : std_logic := '0';
signal sign_a_reg : std_logic := '0';
signal sign_a_pipe : std_logic := '0';
signal sign_a_latent : std_logic := '0';
signal sign_b_reg : std_logic := '0';
signal sign_b_pipe : std_logic := '0';
signal sign_b_latent : std_logic := '0';
signal addsub_reg : std_logic := '0';
signal addsub_pipe : std_logic := '0';
signal addsub_latent : std_logic := '0';
signal accum_sload_latent : std_logic := '0';
signal result_pipe : pipeline_accum := (others => (others => '0'));
signal mult_pipe : pipeline_multi := (others => (others => '0'));
signal temp_mult : std_logic_vector (width_a + width_b -1 downto 0):= (others => '0');
signal mult_out_latent : std_logic_vector (width_a + width_b -1 downto 0):= (others => '0');
signal result_int : std_logic_vector (width_result -1 downto 0):= (others => '0');
signal temp_mult_zero : std_logic_vector (width_a + width_b downto 0):= (others => '0');
signal mult_full : std_logic_vector (width_a + width_b +4 downto 0):= (others => '0');
signal mult_signed, do_add, temp_mult_signed : std_logic := '0';
signal head_result, head_mult : integer := 0;
begin
scanouta <= mult_a;
scanoutb <= mult_b;
sign_a_latent <= mult_full (width_a + width_b + 4) when extra_multiplier_latency >0 else sign_a_reg;
sign_b_latent <= mult_full (width_a + width_b + 3) when extra_multiplier_latency >0 else sign_b_reg;
accum_sload_latent <= mult_full (width_a + width_b + 2) when extra_multiplier_latency >0 else acc_sload_reg;
addsub_latent <= mult_full (width_a + width_b + 1) when extra_multiplier_latency >0 else addsub_reg;
mult_signed <= mult_full (width_a + width_b) when extra_multiplier_latency >0 else temp_mult_signed;
mult_out_latent <= mult_full (width_a + width_b -1 downto 0) when extra_multiplier_latency >0 else temp_mult;
-- Parameter Checking
process (clock0, clock1, clock2, clock3)
begin
if ((dedicated_multiplier_circuitry /= "AUTO") and
(dedicated_multiplier_circuitry /= "YES") and
(dedicated_multiplier_circuitry /= "NO")) then
assert false
report "Error: The DEDICATED_MULTIPLIER_CIRCUITRY parameter is set to an illegal value."
severity error;
end if;
if (width_result < (width_a + width_b)) then
assert false
report "Error: width_result cannot be less than (width_a + width_b)"
severity error;
end if;
if (width_a <= 0) then
assert false
report "Error: width_a must be greater than 0."
severity error;
end if;
if (width_b <= 0) then
assert false
report "Error: width_b must be greater than 0."
severity error;
end if;
if (width_result <= 0) then
assert false
report "Error: width_result must be greater than 0."
severity error;
end if;
end process;
-- ----------------------------------------------------------------------------
-- This process contains 1 register and a combinatorial block (to set mult_a)
-- The signal registered is dataa
--
-- The register has an asynchronous clear and a clock enable signal
-- NOTE: the combinatorial block is trigged if input_reg_a is unregistered and
-- dataa changes value
-- ---------------------------------------------------------------------------
process (clock0, clock1, clock2, clock3, aclr0, aclr1, aclr2, aclr3, dataa)
begin
if (input_reg_a = "UNREGISTERED") then
mult_a <= dataa;
else
if (((input_aclr_a= "ACLR0") and (aclr0 = '1')) or
((input_aclr_a= "ACLR1") and (aclr1 = '1')) or
((input_aclr_a= "ACLR2") and (aclr2 = '1')) or
((input_aclr_a= "ACLR3") and (aclr3 = '1'))) then
mult_a <= (others => '0');
elsif (((input_reg_a = "CLOCK0") and (clock0= '1') and clock0'event and (ena0 ='1')) or
((input_reg_a = "CLOCK1") and (clock1= '1') and clock1'event and (ena1 ='1')) or
((input_reg_a = "CLOCK2") and (clock2= '1') and clock2'event and (ena2 ='1')) or
((input_reg_a = "CLOCK3") and (clock3= '1') and clock3'event and (ena3 ='1'))) then
mult_a <= dataa;
end if;
end if;
end process;
-- ----------------------------------------------------------------------------
-- This process contains 1 register and a combinatorial block (to set mult_b)
-- The signal registered is datab
--
-- The register has an asynchronous clear and a clock enable signal
-- NOTE: the combinatorial block is trigged if input_reg_b is unregistered and
-- datab changes value
-- ---------------------------------------------------------------------------
process (clock0, clock1, clock2, clock3, aclr0, aclr1, aclr2, aclr3, datab)
begin
if (input_reg_b = "UNREGISTERED") then
mult_b <= datab;
else
if (((input_aclr_b= "ACLR0") and (aclr0 = '1')) or
((input_aclr_b= "ACLR1") and (aclr1 = '1')) or
((input_aclr_b= "ACLR2") and (aclr2 = '1')) or
((input_aclr_b= "ACLR3") and (aclr3 = '1'))) then
mult_b <= (others => '0');
elsif (((input_reg_b = "CLOCK0") and (clock0= '1') and clock0'event and (ena0 ='1')) or
((input_reg_b = "CLOCK1") and (clock1= '1') and clock1'event and (ena1 ='1')) or
((input_reg_b = "CLOCK2") and (clock2= '1') and clock2'event and (ena2 ='1')) or
((input_reg_b = "CLOCK3") and (clock3= '1') and clock3'event and (ena3 ='1'))) then
mult_b <= datab;
end if;
end if;
end process;
-- ------------------------------------------------------------------------------
-- This process contains 1 register and a combinatorial block (to set addsub_reg)
-- The signal registered is addnsub
--
-- The register has an asynchronous clear and a clock enable signal
-- NOTE: the combinatorial block is trigged if addnsub_reg is unregistered and
-- addnsub changes value
-- ------------------------------------------------------------------------------
process (clock0, clock1, clock2, clock3, aclr0, aclr1, aclr2, aclr3, addnsub)
begin
if (addnsub_reg = "UNREGISTERED") then
addsub_reg <= addnsub;
else
if (((addnsub_aclr= "ACLR0") and (aclr0 = '1')) or
((addnsub_aclr= "ACLR1") and (aclr1 = '1')) or
((addnsub_aclr= "ACLR2") and (aclr2 = '1')) or
((addnsub_aclr= "ACLR3") and (aclr3 = '1'))) then
addsub_reg <= '0';
elsif (((addnsub_reg = "CLOCK0") and (clock0= '1') and clock0'event and (ena0 ='1')) or
((addnsub_reg = "CLOCK1") and (clock1= '1') and clock1'event and (ena1 ='1')) or
((addnsub_reg = "CLOCK2") and (clock2= '1') and clock2'event and (ena2 ='1')) or
((addnsub_reg = "CLOCK3") and (clock3= '1') and clock3'event and (ena3 ='1'))) then
addsub_reg <= addnsub;
end if;
end if;
end process;
-- ------------------------------------------------------------------------------------
-- This process contains 1 register and a combinatorial block (to set addsub_pipe)
-- The signal registered is addnsub_latent
--
-- The register has an asynchronous clear and a clock enable signal
-- NOTE: the combinatorial block is trigged if addnsub_pipeline_reg is unregistered and
-- addsub_latent changes value
-- ------------------------------------------------------------------------------------
process (clock0, clock1, clock2, clock3, aclr0, aclr1, aclr2, aclr3, addsub_latent)
begin
if (addnsub_pipeline_reg = "UNREGISTERED") then
addsub_pipe <= addsub_latent;
else
if (((addnsub_pipeline_aclr= "ACLR0") and (aclr0 = '1')) or
((addnsub_pipeline_aclr= "ACLR1") and (aclr1 = '1')) or
((addnsub_pipeline_aclr= "ACLR2") and (aclr2 = '1')) or
((addnsub_pipeline_aclr= "ACLR3") and (aclr3 = '1'))) then
addsub_pipe <= '0';
elsif (((addnsub_pipeline_reg = "CLOCK0") and (clock0= '1') and clock0'event and (ena0 ='1')) or
((addnsub_pipeline_reg = "CLOCK1") and (clock1= '1') and clock1'event and (ena1 ='1')) or
((addnsub_pipeline_reg = "CLOCK2") and (clock2= '1') and clock2'event and (ena2 ='1')) or
((addnsub_pipeline_reg = "CLOCK3") and (clock3= '1') and clock3'event and (ena3 ='1'))) then
addsub_pipe <= addsub_latent;
end if;
end if;
end process;
-- ---------------------------------------------------------------------------------
-- This process contains 1 register and a combinatorial block (to set acc_sload_reg)
-- The signal registered is accum_sload
--
-- The register has an asynchronous clear and a clock enable signal
-- NOTE: the combinatorial block is trigged if accum_sload_reg is unregistered and
-- accum_sload changes value
-- ---------------------------------------------------------------------------------
process (clock0, clock1, clock2, clock3, aclr0, aclr1, aclr2, aclr3, accum_sload)
begin
if (accum_sload_reg = "UNREGISTERED") then
acc_sload_reg <= accum_sload;
else
if (((accum_sload_aclr= "ACLR0") and (aclr0 = '1')) or
((accum_sload_aclr= "ACLR1") and (aclr1 = '1')) or
((accum_sload_aclr= "ACLR2") and (aclr2 = '1')) or
((accum_sload_aclr= "ACLR3") and (aclr3 = '1'))) then
acc_sload_reg <= '0';
elsif (((accum_sload_reg = "CLOCK0") and (clock0= '1') and clock0'event and (ena0 ='1')) or
((accum_sload_reg = "CLOCK1") and (clock1= '1') and clock1'event and (ena1 ='1')) or
((accum_sload_reg = "CLOCK2") and (clock2= '1') and clock2'event and (ena2 ='1')) or
((accum_sload_reg = "CLOCK3") and (clock3= '1') and clock3'event and (ena3 ='1'))) then
acc_sload_reg <= accum_sload;
end if;
end if;
end process;
-- ------------------------------------------------------------------------------------
-- This process contains 1 register and a combinatorial block (to set accum_sload_pipe)
-- The signal registered is accum_sload_latent
--
-- The register has an asynchronous clear and a clock enable signal
-- NOTE: the combinatorial block is trigged if accum_sload_pipeline_reg
-- is unregistered and accum_sload_latent changes value
-- ------------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?