⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 altera_mf_87.vhd

📁 一本老师推荐的经典的VHDL覆盖基础的入门书籍
💻 VHD
📖 第 1 页 / 共 5 页
字号:

                if (fb_int >= result_full) then
                    cout_temp :='1';
                else
                    cout_temp :='0';
                end if;
            end if;
        end if;

        if (sload = '0') then
            if ((LPM_REPRESENTATION = "SIGNED") or (sign_data = '1')) then
                overflow_int <= ((not (data (width_in-1) xor result_int (width_out -1))) xor (not (add_sub))) and
                                (result_int (width_out -1) xor temp_sum_int (width_out -1));
            else
                overflow_int <= not (add_sub xor cout_temp);
            end if;
        else
            overflow_int <= '0';
            cout_temp := not add_sub;
        end if;

        cout_int <= cout_temp;
        temp_sum <= temp_sum_int;

    end process ADDSUB;

    ACC: process (clock, aclr, cout_int)

    -- VARIABLE DECLARATIOM
    variable head_pipe : integer;
    variable full_res: std_logic_vector (width_out+1 downto 0);
    begin
        head_pipe := head;

        if (aclr = '1') then
            result <= (others => '0');
            result_int <= (others => '0');
            cout <= '0';
            overflow <= '0';
            result_pipe <= (others => (others => '0'));
        else
            if (extra_latency = 0) then
                cout <= cout_int;
            end if;

            if (clock'event and (clock = '1' and clken = '1')) then
                if (extra_latency > 0) then
                    result_pipe (head_pipe) <= (result_int (width_out+1) &
                                                cout_int &
                                                result_int (width_out-1 downto 0));

                    head_pipe := (head_pipe + 1) mod (extra_latency);
                    if (head_pipe = head) then
                        full_res := (result_int (width_out+1) &
                                     cout_int &
                                     result_int (width_out-1 downto 0));
                    else
                        full_res := result_pipe (head_pipe);
                    end if;
                    cout <= full_res (width_out);
                    result <= full_res (width_out-1 downto 0);
                    overflow <= full_res (width_out+1);
                else
                    overflow <= overflow_int;
                    result <= temp_sum (width_out-1 downto 0);
                end if;
                result_int <= (overflow_int & cout_int &
                               temp_sum (width_out-1 downto 0));
            end if;
        end if;

        head <= head_pipe;
    end process ACC;

end behaviour; -- End behaviour of altaccumulate
-- END OF ARCHITECTURE

-- --------------------------------------------------------------------------
-- Module Name      : altmult_accum
--
-- Description      : a*b + x (MAC)
--
-- Limitation       : Stratix DSP block
--
-- Results expected : signed & unsigned, maximum of 3 pipelines(latency) each.
--
-- --------------------------------------------------------------------------

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use work.ALTERA_DEVICE_FAMILIES.all;

entity altmult_accum is
    generic (

        -- ---------------------
        -- PARAMETER DECLARATION
        -- ---------------------
        width_a                        : integer := 1;
        width_b                        : integer := 1;
        width_result                   : integer := 2;
        width_upper_data               : integer := 1;
        input_source_a                 : string  := "DATAA";
        input_source_b                 : string  := "DATAB";
        input_reg_a                    : string  := "CLOCK0";
        input_aclr_a                   : string  := "ACLR3";
        input_reg_b                    : string  := "CLOCK0";
        input_aclr_b                   : string  := "ACLR3";
        addnsub_reg                    : string  := "CLOCK0";
        addnsub_aclr                   : string  := "ACLR3";
        addnsub_pipeline_reg           : string  := "CLOCK0";
        addnsub_pipeline_aclr          : string  := "ACLR3";
        accum_direction                : string  := "ADD";
        accum_sload_reg                : string  := "CLOCK0";
        accum_sload_aclr               : string  := "ACLR3";
        accum_sload_pipeline_reg       : string  := "CLOCK0";
        accum_sload_pipeline_aclr      : string  := "ACLR3";
        representation_a               : string  := "UNSIGNED";
        sign_reg_a                     : string  := "CLOCK0";
        sign_aclr_a                    : string  := "ACLR3";
        sign_pipeline_reg_a            : string  := "CLOCK0";
        sign_pipeline_aclr_a           : string  := "ACLR3";
        representation_b               : string  := "UNSIGNED";
        sign_reg_b                     : string  := "CLOCK0";
        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";
        intended_device_family         : string  := "Stratix";
        multiplier_rounding            : string  := "NO";
        mult_round_aclr                : string  := "ACLR3";
        mult_round_reg                 : string  := "CLOCK0";
        multiplier_saturation          : string  := "NO";
        mult_saturation_aclr           : string  := "ACLR3";
        mult_saturation_reg            : string  := "CLOCK0";
        accumulator_rounding           : string  := "NO";
        accum_round_aclr               : string  := "ACLR3";
        accum_round_reg                : string  := "CLOCK0";
        accum_round_pipeline_aclr      : string  := "ACLR3";
        accum_round_pipeline_reg       : string  := "CLOCK0";
        accumulator_saturation         : string  := "NO";
        accum_saturation_aclr          : string  := "ACLR3";
        accum_saturation_reg           : string  := "CLOCK0";
        accum_saturation_pipeline_aclr : string  := "ACLR3";
        accum_saturation_pipeline_reg  : string  := "CLOCK0";
        accum_sload_upper_data_aclr    : string  := "ACLR3";
        accum_sload_upper_data_pipeline_aclr : string  := "ACLR3";
        accum_sload_upper_data_pipeline_reg  : string  := "CLOCK0";
        accum_sload_upper_data_reg     : string  := "CLOCK0";
        port_mult_is_saturated         : string  := "UNUSED";
        port_accum_is_saturated        : string  := "UNUSED"
    );

    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);
        scanina     : in std_logic_vector(width_a -1 downto 0) := (others => 'Z');
        scaninb     : in std_logic_vector(width_b -1 downto 0) := (others => 'Z');
        accum_sload_upper_data : in std_logic_vector(width_upper_data - 1 downto 0) := (others => '0');
        sourcea     : in std_logic := '1';
        sourceb     : in std_logic := '1';
        -- 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';
        -- round and saturation ports
        mult_round       : in std_logic := '0';
        mult_saturation  : in std_logic := '0';
        accum_round      : in std_logic := '0';
        accum_saturation : 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');
        mult_is_saturated  : out std_logic := '0';
        accum_is_saturated : out std_logic := '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 + 4 downto 0);
    type pipeline_sload is array (extra_multiplier_latency downto 0) of std_logic_vector (width_result -1 +4 downto 0);

    -- -------------------------------------
    -- INTERNAL SIGNALS AND TYPE DECLARATION
    -- -------------------------------------

    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 + 4 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 sload_upper_data_pipe    : pipeline_sload := (others => (others => '0'));

    signal mult_out_latent : std_logic_vector (width_a + width_b -1 + 4 downto 0):= (others => '0');
    signal result_int      : std_logic_vector (width_result -1 + 4 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 + 4 downto 0):= (others => '0');

    signal mult_signed      : std_logic := '0';
    signal do_add           : std_logic := '0';
    signal temp_mult_signed : std_logic := '0';
    signal head_result      : integer   := 0;
    signal head_mult        : integer   := 0;

    signal lower_bits              : std_logic_vector (width_result + width_upper_data -1 + 4 downto 0) := (others => '0');
    signal sload_upper_data_reg    : std_logic_vector (width_result -1 +4 downto 0) := (others => '0');
    signal sload_upper_data_latent : std_logic_vector (width_result -1 +4 downto 0) := (others => '0');
    signal sload_upper_data_wire    : std_logic_vector (width_result -1 +4 downto 0) := (others => '0');
    signal sload_upper_data_full    : std_logic_vector (width_result -1 +4 downto 0) := (others => '0');

    signal mult_is_saturated_wire : std_logic := '0';
    signal mult_is_saturated_reg  : std_logic := '0';
    signal mult_is_saturated_out  : std_logic := '0';
    signal accum_is_saturated_out : std_logic := '0';

    signal mult_round_wire : std_logic := '0';
    signal mult_saturate_wire : std_logic := '0';
    signal mult_final_out : std_logic_vector (width_a + width_b - 1 + 4 downto 0) := (others => '0');

    signal accum_round_pipe_wire : std_logic := '0';
    signal accum_round_wire : std_logic := '0';
    signal accum_saturation_pipe_wire : std_logic := '0';
    signal accum_saturate_wire : std_logic := '0';
    
    begin

        scanouta           <= mult_a;
        scanoutb           <= mult_b;
        sign_a_latent      <= mult_full (width_a + width_b + 4 + 4) when extra_multiplier_latency >0 else sign_a_reg;
        sign_b_latent      <= mult_full (width_a + width_b + 3 + 4) when extra_multiplier_latency >0 else sign_b_reg;
        accum_sload_latent <= mult_full (width_a + width_b + 2 + 4) when extra_multiplier_latency >0 else acc_sload_reg;
        addsub_latent      <= mult_full (width_a + width_b + 1 + 4) when extra_multiplier_latency >0 else addsub_reg;
        mult_signed        <= mult_full (width_a + width_b + 4) when extra_multiplier_latency >0 else temp_mult_signed;
        mult_out_latent    <= mult_full (width_a + width_b -1 + 4 downto 0) when extra_multiplier_latency >0 else mult_final_out;

⌨️ 快捷键说明

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