📄 新建 文本文档.txt
字号:
---------------------------------------------------------------------------
-- lvds receiver megafunction
----------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
entity altlvds_rx is
generic
( number_of_channels : natural;
deserialization_factor : natural;
inclock_boost : natural := 0;
registered_output : string := "ON";
inclock_period : natural;
clock_setting : string := "UNUSED";
cds_mode : string := "UNUSED";
intended_device_family : string := "APEX20KE";
input_data_rate: natural := 0;
inclock_data_alignment:string:= "EDGE_ALIGNED";
registered_data_align_input:string:="ON";
common_rx_tx_pll:string:="ON");
port
( rx_in : in std_logic_vector(number_of_channels-1 downto 0);
rx_inclock : in std_logic;
rx_deskew : in std_logic := '0';
rx_pll_enable : in std_logic := '1';
rx_data_align : in std_logic := '0';
rx_out : out std_logic_vector(deserialization_factor*number_of_channels -1 downto 0);
rx_outclock : out std_logic;
rx_locked : out std_logic );
function clock_boost_calc (constant i_input_data_rate, i_inclock_period, i_deserialization_factor, i_inclock_boost : in natural) return natural is
variable i_input_clock_boost: natural;
begin
if (i_input_data_rate /= 0 and i_inclock_period /= 0) then
i_input_clock_boost := (i_input_data_rate * 100) / i_inclock_period;
else
if inclock_boost =0 then
i_input_clock_boost := i_deserialization_factor;
else
i_input_clock_boost := i_inclock_boost;
end if;
end if;
return i_input_clock_boost;
end clock_boost_calc;
function get_phase_delay (constant i_phase_delay : in string) return string is
variable my_phase : string (1 to 11);
begin
-- returns the delay in radians
if i_phase_delay = "EDGE_ALIGNED" then
my_phase := "0.000000000";
elsif i_phase_delay = "CENTER_ALIGNED" then
my_phase := "1.570796326";
elsif i_phase_delay = "45_DEGREES" then
my_phase := "0.785398163";
elsif i_phase_delay = "135_DEGREES" then
my_phase := "2.356194490";
elsif i_phase_delay = "180_DEGREES" then
my_phase := "3.141592653";
elsif i_phase_delay = "225_DEGREES" then
my_phase := "3.926990816";
elsif i_phase_delay = "270_DEGREES" then
my_phase := "4.712388980";
elsif i_phase_delay = "315_DEGREES" then
my_phase := "5.497787143";
end if;
return my_phase;
end get_phase_delay;
end altlvds_rx;
architecture behavior of altlvds_rx is
type channel_cnt is array (number_of_channels-1 downto 0) of integer;
signal rx_out_rgd : std_logic_vector(deserialization_factor*number_of_channels -1 downto 0) := (others => '0');
signal rx_hold_rgd : std_logic_vector(deserialization_factor*number_of_channels -1 downto 0) := (others => '0');
signal rx_out_int : std_logic_vector(deserialization_factor*number_of_channels -1 downto 0);
signal data_out : std_logic_vector(deserialization_factor*number_of_channels -1 downto 0);
signal rx_clock0_int : std_logic;
signal rx_clock1_int : std_logic;
signal rx_pll_clk0 : std_logic;
signal rx_pll_clk1 : std_logic;
signal apex20ke_locked_int: std_logic;
signal apex20ke_pll_clk0: std_logic;
signal apex20ke_pll_clk1: std_logic;
signal mercury_locked_int_deser: std_logic;
signal mercury_pll_clk0_deser: std_logic;
signal mercury_pll_clk1_deser: std_logic;
signal mercury_locked_int_boost: std_logic;
signal mercury_pll_clk0_boost: std_logic;
signal mercury_pll_clk1_boost: std_logic;
signal mercury_locked_int: std_logic;
signal mercury_pll_clk0: std_logic;
signal mercury_pll_clk1: std_logic;
signal rx_mercury_slow_clock : std_logic;
signal rx_locked_int : std_logic;
signal deskew_done: std_logic_vector(number_of_channels-1 downto 0) := (others => '1');
signal calibrate: std_logic_vector(number_of_channels-1 downto 0) := (others => '0');
signal apex20ke_en: std_logic;
signal mercury_en: std_logic;
signal mercury_boost_en: std_logic;
signal first_load : std_logic := '0';
signal temp_zero : std_logic := '0';
signal temp_high : std_logic_vector (1 to 5) := (others => '1');
signal temp_clk : std_logic_vector (1 to 4):= (others => '0');
--signal input_clock_boost: natural:=0;
signal deser_boost:natural:=0;
signal rx_data_align_reg: std_logic := '0';
component altclklock
generic
( inclock_period : natural := 10000;
clock0_boost : natural := 1;
clock1_boost : natural := 1;
clock1_divide : natural := 1;
valid_lock_cycles : natural := 1;
intended_device_family : string := "APEX20KE";
outclock_phase_shift : natural :=0 );
port
( inclock : in std_logic;
inclocken : in std_logic;
clock0 : out std_logic;
clock1 : out std_logic;
locked : out std_logic );
end component;
component altpll
generic (
inclk0_input_frequency : positive ;
clk1_multiply_by : positive := 1;
clk0_multiply_by : positive := 1;
clk1_divide_by : positive := 1;
clk0_phase_shift : string := "0";
device_family : string := "Stratix"
);
port (
inclk : in std_logic_vector(1 downto 0) := (others => '0');
clkena : in std_logic_vector(5 downto 0) := (others => '1');
clk : out std_logic_vector(5 downto 0);
locked : out std_logic
);
end component;
begin
process (rx_clock0_int, rx_data_align)
begin
if (rx_clock0_int='1' and rx_clock0_int'event) or registered_data_align_input /= "ON" then
rx_data_align_reg <= rx_data_align;
end if;
end process;
rx_out <= rx_out_rgd when registered_output = "ON" else rx_out_int;
rx_out_int <= rx_hold_rgd when (deserialization_factor > 2 and deserialization_factor < 7) else data_out;
rx_clock0_int <= rx_pll_clk0 when deserialization_factor > 1 else rx_inclock;
rx_clock1_int <= rx_pll_clk1 when deserialization_factor > 1 else rx_inclock;
rx_outclock <= rx_clock1_int;
rx_locked <= rx_locked_int when deserialization_factor > 1 else '1';
mercury_pll_clk0 <= mercury_pll_clk0_deser when inclock_boost = 0 else mercury_pll_clk0_boost;
mercury_pll_clk1 <= mercury_pll_clk1_deser when inclock_boost = 0 else mercury_pll_clk1_boost;
rx_pll_clk0 <= mercury_pll_clk0 when (intended_device_family = "MERCURY" or intended_device_family = "STRATIX") else apex20ke_pll_clk0;
rx_pll_clk1 <= rx_mercury_slow_clock when (intended_device_family = "MERCURY" or intended_device_family = "STRATIX") else apex20ke_pll_clk1;
mercury_locked_int <= mercury_locked_int_deser when inclock_boost = 0 else mercury_locked_int_boost;
rx_locked_int <= mercury_locked_int when (intended_device_family = "MERCURY" or intended_device_family = "STRATIX") else apex20ke_locked_int;
apex20ke_en <= rx_pll_enable when ( intended_device_family = "APEX20KE" or intended_device_family = "APEX20KC" or
(intended_device_family = "APEXII" or intended_device_family = "APEX II" or intended_device_family = "STRATIX") or
intended_device_family = "EXCALIBUR_ARM" or intended_device_family = "EXCALIBUR_MIPS") else '0';
mercury_en <= rx_pll_enable when ((intended_device_family = "MERCURY" or intended_device_family = "STRATIX") and inclock_boost = 0) else '0';
mercury_boost_en <= rx_pll_enable when ((intended_device_family = "MERCURY" or intended_device_family = "STRATIX") and inclock_boost /= 0) else '0';
deser_boost <= deserialization_factor when inclock_boost = 0 else inclock_boost ;
--input_clock_boost := deser_boost;
U0: altclklock -- APEX20KE PLL
generic map
( inclock_period => inclock_period,
clock0_boost => deserialization_factor, clock1_boost => 1,
valid_lock_cycles => 5,
intended_device_family => intended_device_family)
port map
( inclock => rx_inclock, inclocken => apex20ke_en,
clock0 => apex20ke_pll_clk0, clock1 => apex20ke_pll_clk1,
locked => apex20ke_locked_int );
U1: altclklock -- MERCURY PLL without inclock boost
generic map
( inclock_period => inclock_period,
clock0_boost => deserialization_factor, clock1_boost => 1,
valid_lock_cycles => 3,
intended_device_family => intended_device_family)
port map
( inclock => rx_inclock, inclocken => mercury_en,
clock0 => mercury_pll_clk0_deser, clock1 => mercury_pll_clk1_deser,
locked => mercury_locked_int_deser );
YEAGER_PLL:
if intended_device_family = "STRATIX" generate
U2: altpll -- STRATIX PLL
generic map
( inclk0_input_frequency => inclock_period,
clk0_multiply_by => clock_boost_calc (input_data_rate, inclock_period, deserialization_factor, inclock_boost),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -