altera_mf_87.vhd
来自「一个非常好的dc使用书籍 一个非常好的dc使用书籍」· VHDL 代码 · 共 1,443 行 · 第 1/5 页
VHD
1,443 行
if (pos >= 1) then
read(str_line, str);
end if;
end;
end ALTERA_COMMON_CONVERSION;
-- END OF PACKAGE
---START_ENTITY_HEADER---------------------------------------------------------
--
-- Entity Name : altaccumulate
--
-- Description : Parameterized accumulator megafunction. The accumulator
-- performs an add function or a subtract function based on the add_sub
-- parameter. The input data can be signed or unsigned.
--
-- Limitation : n/a
--
-- Results expected: result - The results of add or subtract operation. Output
-- port [width_out-1 .. 0] wide.
-- cout - The cout port has a physical interpretation as
-- the carry-out (borrow-in) of the MSB. The cout
-- port is most meaningful for detecting overflow
-- in unsigned operations. The cout port operates
-- in the same manner for signed and unsigned
-- operations.
-- overflow - Indicates the accumulator is overflow.
--
---END_ENTITY_HEADER-----------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
-- BEGINNING OF ENTITY
entity altaccumulate is
-- GENERIC DECLARATION
generic (
width_in : integer := 4; -- Required
width_out : integer := 8; -- Required
lpm_representation : string := "UNSIGNED";
extra_latency : integer := 0;
use_wys : string := "ON";
lpm_hint : string := "UNUSED";
lpm_type : string := "altaccumulate"
);
-- PORT DECLARATION
port (
-- INPUT PORT DECLARATION
cin : in std_logic := 'Z';
data : in std_logic_vector(width_in -1 downto 0); -- Required port
add_sub : in std_logic := '1';
clock : in std_logic; -- Required port
sload : in std_logic := '0';
clken : in std_logic := '1';
sign_data : in std_logic := '0';
aclr : in std_logic := '0';
-- OUTPUT PORT DECLARATION
result : out std_logic_vector(width_out -1 downto 0) := (others => '0'); -- Required port
cout : out std_logic := '0';
overflow : out std_logic := '0'
);
end altaccumulate;
-- END OF ENTITY
-- BEGINNING OF ARCHITECTURE
architecture behaviour of altaccumulate is
-- TYPE DECLARATION
type pipeline is array (extra_latency-1 downto 0) of std_logic_vector (width_out+1 downto 0);
-- SIGNAL DECLARATION
signal temp_sum : std_logic_vector (width_out downto 0) := (others => '0');
signal cout_int : std_logic := '0';
signal overflow_int : std_logic := '0';
signal result_int : std_logic_vector (width_out+1 downto 0) := (others => '0');
signal result_pipe : pipeline := (others => (others => '0'));
signal head : integer := 0;
begin
MSG: process
begin
if( width_in <= 0 ) then
ASSERT FALSE
REPORT "Error! Value of width_in parameter must be greater than 0."
SEVERITY ERROR;
end if;
if( width_out <= 0 ) then
ASSERT FALSE
REPORT "Error! Value of width_out parameter must be greater than 0."
SEVERITY ERROR;
end if;
if( extra_latency > width_out ) then
ASSERT FALSE
REPORT "Info: Value of extra_latency parameter should be lower than width_out parameter for better performance/utilization."
SEVERITY NOTE;
end if;
if( width_in > width_out ) then
ASSERT FALSE
REPORT "Error! Value of width_in parameter should be lower than or equal to width_out."
SEVERITY ERROR;
end if;
wait;
end process MSG;
-- PROCESS DECLARATION
ADDSUB : process (data, add_sub, sload, cin, sign_data,
result_int (width_out-1 downto 0))
-- VARIABLE DECLARATIOM
variable fb_int : std_logic_vector (width_out downto 0) := (others => '0');
variable data_int : std_logic_vector (width_out-1 downto 0) := (others => '0');
variable zeropad : std_logic_vector ((width_out - width_in)-1 downto 0) := (others => '0');
variable temp_sum_int : std_logic_vector (width_out downto 0) := (others => '0');
variable cout_temp, borrow : std_logic;
variable result_full : std_logic_vector (width_out downto 0);
variable temp_sum_zero : std_logic_vector (width_out downto 0) := (others => '0');
variable cin_int : std_logic;
begin
if ((LPM_REPRESENTATION = "SIGNED") or (sign_data = '1')) then
zeropad := (others => data (width_in-1));
else
zeropad := (others => '0');
end if;
if (sload = '1') then
fb_int := (others => '0');
else
fb_int := ('0' & result_int (width_out-1 downto 0));
end if;
if ((data (0) = '1') or (data (0) = '0')) then
data_int := (zeropad & data);
end if;
-- If cin is omitted (i.e. cin = 'z'), cin default is 0 for add operation
-- and 1 for subtract operation.
if ((cin /= '0') and (cin /= '1')) then
cin_int := not add_sub;
else
cin_int := cin;
end if;
if (sload = '1') then
temp_sum_int := unsigned(temp_sum_zero) + unsigned(data_int);
else
if (add_sub = '1') then
temp_sum_int := unsigned(temp_sum_zero) + unsigned(fb_int) +
unsigned(data_int) + cin_int;
cout_temp := temp_sum_int(width_out);
else
borrow := not cin_int;
if ((borrow /= '1') and (borrow /= '0')) then
borrow := '0';
end if;
temp_sum_int := unsigned(temp_sum_zero) + unsigned (fb_int) -
unsigned (data_int) - borrow;
result_full := unsigned(temp_sum_zero) + unsigned(data_int) +
borrow;
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;
entity altmult_accum is
generic (
-- ---------------------
-- PARAMETER DECLARATION
-- ---------------------
width_a : integer := 1;
width_b : integer := 1;
width_result : integer := 2;
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";
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?