altera_mf_87.vhd

来自「一个非常好的dc使用书籍 一个非常好的dc使用书籍」· VHDL 代码 · 共 1,443 行 · 第 1/5 页

VHD
1,443
字号
                    result_temp := (others => '0');
                else
                    result_temp := result_int;
                end if;


                if (addsub_int = '1') then -- add the numbers if the add flag is turned on
                    temp_sum := unsigned(temp_sum_zero)+ unsigned (result_temp) + unsigned (mult_res_temp);
                    cout_int := temp_sum (width_result);
                else -- subtract the numbers if the add flag is turned off
                    temp_sum := unsigned(temp_sum_zero)+ unsigned (result_temp) - unsigned (mult_res_temp);

                    if (result_temp >= unsigned(temp_sum_zero (width_result -1 downto 0)) + unsigned (mult_res_temp)) then
                        cout_int := '1';
                    else
                        cout_int := '0';
                    end if;
                end if;

                if (signed_int = '1' and (not (mult_res = temp_mult_zero))) then
                    overflow_int := (((not (mult_res (width_a + width_b-1) xor result_temp (width_result -1))) xor (not (addsub_int)))
                                     and (result_temp (width_result -1) xor temp_sum (width_result -1)));
                else
                    overflow_int := not (addsub_int xor cout_int);
                end if;

                if (extra_accumulator_latency = 0) then
                    result   <= temp_sum (width_result-1 downto 0);
                    overflow <= overflow_int;
                else
                    head_result_int               := head_result;
                    result_pipe (head_result_int) <= (overflow_int & temp_sum (width_result-1 downto 0));
                    head_result_int               := (head_result_int +1) mod (extra_accumulator_latency);
                    result_full                   := result_pipe(head_result_int);
                    result                        <= result_full (width_result-1 downto 0);
                    overflow                      <= result_full (width_result);
                end if;

                result_int <= temp_sum (width_result-1 downto 0);
            end if;
        end process;

end behaviour;  -- end of ALT_MULT_ACCUM

----------------------------------------------------------------------------
-- Module Name      : altmult_add
--
-- Description      : a*b + c*d
--
-- Limitation       : Stratix DSP block
--
-- Results expected : signed & unsigned, maximum of 3 pipelines(latency) each.
--                    possible of zero pipeline.
--
----------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;

entity     altmult_add is
    generic (

        -- ---------------------
        -- PARAMETER DECLARATION
        -- ---------------------
        width_a               : integer := 1;
        width_b               : integer := 1;
        width_result          : integer := 1;
        number_of_multipliers : integer := 1;
                
        -- A inputs
        input_register_a0 : string := "CLOCK0";
        input_aclr_a0     : string := "ACLR3";
        input_source_a0   : string := "DATAA";

        input_register_a1 : string := "CLOCK0";
        input_aclr_a1     : string := "ACLR3";
        input_source_a1   : string := "DATAA";

        input_register_a2 : string := "CLOCK0";
        input_aclr_a2     : string := "ACLR3";
        input_source_a2   : string := "DATAA";

        input_register_a3 : string := "CLOCK0";
        input_aclr_a3     : string := "ACLR3";
        input_source_a3   : string := "DATAA";

        representation_a           : string := "UNSIGNED";
        signed_register_a          : string := "CLOCK0";
        signed_aclr_a              : string := "ACLR3";
        signed_pipeline_register_a : string := "CLOCK0";
        signed_pipeline_aclr_a     : string := "ACLR3";

        -- B inputs
        input_register_b0 : string := "CLOCK0";
        input_aclr_b0     : string := "ACLR3";
        input_source_b0   : string := "DATAB";

        input_register_b1 : string := "CLOCK0";
        input_aclr_b1     : string := "ACLR3";
        input_source_b1   : string := "DATAB";

        input_register_b2 : string := "CLOCK0";
        input_aclr_b2     : string := "ACLR3";
        input_source_b2   : string := "DATAB";

        input_register_b3 : string := "CLOCK0";
        input_aclr_b3     : string := "ACLR3";
        input_source_b3   : string := "DATAB";

        representation_b           : string := "UNSIGNED";
        signed_register_b          : string := "CLOCK0";
        signed_aclr_b              : string := "ACLR3";
        signed_pipeline_register_b : string := "CLOCK0";
        signed_pipeline_aclr_b     : string := "ACLR3";

        -- Multiplier parameter
        multiplier_register0 : string := "CLOCK0";
        multiplier_aclr0     : string := "ACLR3";
        multiplier_register1 : string := "CLOCK0";
        multiplier_aclr1     : string := "ACLR3";
        multiplier_register2 : string := "CLOCK0";
        multiplier_aclr2     : string := "ACLR3";
        multiplier_register3 : string := "CLOCK0";
        multiplier_aclr3     : string := "ACLR3";

        addnsub_multiplier_register1          : string := "CLOCK0";
        addnsub_multiplier_aclr1              : string := "ACLR3";
        addnsub_multiplier_pipeline_register1 : string := "CLOCK0";
        addnsub_multiplier_pipeline_aclr1     : string := "ACLR3";
                
        addnsub_multiplier_register3          : string := "CLOCK0";
        addnsub_multiplier_aclr3              : string := "ACLR3";
        addnsub_multiplier_pipeline_register3 : string := "CLOCK0";
        addnsub_multiplier_pipeline_aclr3     : string := "ACLR3";
            
        multiplier1_direction : string := "ADD";
        multiplier3_direction : string := "ADD";            

        -- output parameters
        output_register : string := "CLOCK0";
        output_aclr     : string := "ACLR0";

        -- General setting parameters
        extra_latency                  : integer := 0;
        dedicated_multiplier_circuitry : string  := "AUTO";
        dsp_block_balancing            : string  := "AUTO";
        lpm_hint                       : string  := "UNUSED";
        lpm_type                       : string  := "altmult_add";
        intended_device_family         : string  := "Stratix"
    );
                        
    port (

        -- ----------------
        -- PORT DECLARATION
        -- ----------------

        -- data input ports
        dataa : in std_logic_vector(number_of_multipliers * width_a -1 downto 0);
        datab : in std_logic_vector(number_of_multipliers * width_b -1 downto 0);
                
        -- clock ports
        clock3 : in std_logic := '1';
        clock2 : in std_logic := '1';
        clock1 : in std_logic := '1';
        clock0 : in std_logic := '1';

        -- clear ports
        aclr3 : in std_logic := '0';
        aclr2 : in std_logic := '0';
        aclr1 : in std_logic := '0';
        aclr0 : in std_logic := '0';

        -- clock enable signals
        ena3 : in std_logic := '1';
        ena2 : in std_logic := '1';
        ena1 : in std_logic := '1';
        ena0 : in std_logic := '1';

        -- control signals
        signa    : in std_logic := 'Z';
        signb    : in std_logic := 'Z';
        addnsub1 : in std_logic := 'Z';
        addnsub3 : in std_logic := 'Z';

        -- output ports
        result   : out std_logic_vector(width_result -1 downto 0) := (others => '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_add;

architecture behaviour of altmult_add is

    -- ---------------------------
    -- SIGNAL AND TYPE DECLARATION
    -- ---------------------------
    type pipeline_accum is array (extra_latency downto 0) of std_logic_vector (width_result-1 downto 0); 

    signal zeropad  : std_logic_vector ((width_result - width_a - width_b)/2  -1 downto 0) := (others => '0');
    signal answer   : std_logic_vector (width_result + 1 downto 0) := (others => '0');
    signal mult_a   : std_logic_vector ((4 * width_a) -1 downto 0) := (others => '0');
    signal mult_b   : std_logic_vector ((4 * width_b) -1 downto 0) := (others => '0');
    signal mult_res : std_logic_vector (number_of_multipliers * (width_a + width_b) -1 downto 0) := (others => '0');

    signal zero_acc_reg  : std_logic := '0';
    signal zero_acc_pipe : std_logic := '0';
    signal sign_a_reg    : std_logic := '0';
    signal sign_a_pipe   : std_logic := '0';
    signal sign_b_reg    : std_logic := '0';
    signal sign_b_pipe   : std_logic := '0';
    signal addsub_reg1   : std_logic := '0';
    signal addsub_pipe1  : std_logic := '0';
    signal addsub_reg3   : std_logic := '0';
    signal addsub_pipe3  : std_logic := '0';

    signal out_sum     : std_logic_vector (width_result + 1 downto 0);
    signal result_pipe : pipeline_accum := (others => (others => '0'));

    signal mult_clock : std_logic_vector (3 downto 0) := (others => '0');
    signal mult_ena   : std_logic_vector (3 downto 0) := (others => '0');
    signal mult_aclr  : std_logic_vector (3 downto 0) := (others => '0');

    signal clock_vector : std_logic_vector (3 downto 0) := (others => '0');
    signal ena_vector   : std_logic_vector (3 downto 0) := (others => '0');
    signal aclr_vector  : std_logic_vector (3 downto 0) := (others => '0');

    signal dataa_int      : std_logic_vector (4 * width_a -1 downto 0) := (others => '0');
    signal datab_int      : std_logic_vector (4 * width_b -1 downto 0) := (others => '0');
    signal is_reg         : std_logic_vector (3 downto 0) := (others => '0'); 
    signal temp_mult_zero : std_logic_vector ((width_a + width_b) -1 downto 0) := (others => '0');

    signal head_result    : integer := 0;
    signal signed_mult    : std_logic := '1';


    -- -------------------------------------------------------------------
    -- This function takes in a string that describes the clock name
    -- and returns the correct number that corresponds to that particular
    -- clock signal
    -- -------------------------------------------------------------------
    function resolve_clock (ARG : string) return integer is
        variable clock_num:integer := 0;
    begin
        if (ARG = "CLOCK0") then
            clock_num := 0;
        elsif ARG = "CLOCK1" then
            clock_num := 1;
        elsif ARG = "CLOCK2" then
            clock_num := 2;
        elsif ARG = "CLOCK3" then
            clock_num := 3;
        end if;

        return clock_num;
    end resolve_clock;


    -- -------------------------------------------------------------------
    -- This function takes in a string that describes the clear name
    -- and returns the correct number that corresponds to that particular
    -- clear signal
    -- -------------------------------------------------------------------
    function resolve_aclr (ARG : string) return integer is
        variable aclr_num:integer := 0;
    begin
        if (ARG = "ACLR0") then
            aclr_num := 0;
        elsif ARG = "ACLR1" then
            aclr_num := 1;
        elsif ARG = "ACLR2" then
            aclr_num := 2;
        elsif ARG = "ACLR3" then
            aclr_num := 3;
        end if;

        return aclr_num;
    end resolve_aclr;


    -- -------------------------------------------------------------------
    -- This function takes in a integer that describes the particular
    -- clock signal returns the correct string 
    -- -------------------------------------------------------------------
    functi

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?