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

📄 apex20ke_mf.vhd

📁 用VHDL编写DDR SDRAM Controller的源代码
💻 VHD
📖 第 1 页 / 共 3 页
字号:
         locked: out std_logic);
end altclklock;

architecture behavior of altclklock is

  signal pll0_period : TIME ;
  signal pll1_period : TIME ;
  signal new_clock0 : std_logic ;
  signal new_clock1 : std_logic ;
  signal start_new_clock0 : std_logic;
  signal start_new_clock1 : std_logic;
  signal phase_delay0 : TIME;
  signal phase_delay1 : TIME;
  signal locked_int : std_logic := '0';
  signal highcycle, lowcycle: time := 0 ps;
  signal cycleviolation : std_logic := '0';

begin


lock: process(inclock, inclocken)

variable inclock_edge_count: integer := 0;
variable outclock_start_edge : std_logic ;
begin

   if locked_int = '0' then
      pll0_period <= real(real(real(clock0_divide)/real(clock0_boost))* real(inclock_period )) * 1 ps;
      pll1_period <= real(real(real(clock1_divide)/real(clock1_boost))* real(inclock_period )) * 1 ps;

      if outclock_phase_shift = 0 then
         outclock_start_edge := '1'; 
         phase_delay0 <= (0.5 ) * pll0_period;
         phase_delay1 <= (0.5 ) * pll1_period;
      else
        phase_delay0 <= outclock_phase_shift * 1 ps;
        phase_delay1 <= outclock_phase_shift * 1 ps;
      end if;

        start_new_clock0 <= outclock_start_edge;
        start_new_clock1 <= outclock_start_edge;
   end if;
      
   if inclocken = '0' or cycleviolation = '1' then
      inclock_edge_count := 0;
      locked_int <= '0';
      locked <= '0';
   elsif inclock'event then -- any inclock edge
      if inclock = '1' then
         if (((NOW - lowcycle) /= (1 ps * inclock_period/2))and (NOW > (1 ps * inclock_period/2))) then
            cycleviolation <= '1';
	    assert false
            report "Duty cycle violation"
            severity error; 
         end if;
         highcycle <= NOW;
      end if;
      if inclock = '0' then
         if ((NOW - highcycle) /= (1 ps * inclock_period/2)) then
            cycleviolation <= '1';
	    assert false
            report "Duty cycle violation"
            severity error; 
         end if;
         lowcycle <= NOW;
      end if;
      inclock_edge_count := inclock_edge_count + 1; 
      if inclock_edge_count = valid_lock_cycles then
         cycleviolation <= '0';
         locked_int <= '1';
         locked <= '1';
      end if;
   end if;

end process;

gen_clock0: process(new_clock0,locked_int)
variable first_cycle: boolean := true;
begin
      if locked_int = '1' then
         if first_cycle = true then
            clock0 <= start_new_clock0;
            new_clock0 <= not start_new_clock0 after phase_delay0;
         else
            clock0 <= new_clock0; 
            new_clock0 <= not new_clock0 after pll0_period/2;
         end if;
         first_cycle := false;
      else
         first_cycle := true;
      end if;
end process;

gen_clock1: process(new_clock1,locked_int)
variable first_cycle: boolean := true;
begin
      if locked_int = '1' then
         if first_cycle = true then
            clock1 <= start_new_clock1;
            new_clock1 <= not start_new_clock1 after phase_delay1;
         else
            clock1 <= new_clock1; 
            new_clock1 <= not new_clock1 after pll1_period/2;
         end if;
         first_cycle := false;
      else
         first_cycle := true;
      end if;
end process;

          
end behavior;

-- 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;
            registered_output: string := "ON";
            inclock_period: natural;
            clock_setting: string := "UNUSED");
    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_out: out std_logic_vector(deserialization_factor*number_of_channels -1 downto 0);
          rx_outclock : out std_logic;
          rx_locked : out std_logic);
end altlvds_rx;

architecture behavior of altlvds_rx is
type channel_cnt is array (number_of_channels-1 downto 0) of integer;
signal data_int2, data_int3, data_regs: std_logic_vector(deserialization_factor*number_of_channels -1 downto 0);
signal rx_clkout_int : std_logic;
signal rx_locked_int : std_logic;
signal deskew_done: std_logic_vector(number_of_channels-1 downto 0) := (others => '1');
signal en: std_logic := '1';
signal first_load : std_logic := '0';
component altclklock
   generic (
            inclock_period : natural;
            inclock_settings : string := "UNUSED";
            valid_lock_cycles : natural := 3;
            invalid_lock_cycles : natural := 3;
            operation_mode : string := "NORMAL";
            clock0_boost : natural := 1;
            clock0_divide : natural := 1;
            clock1_boost : natural := 1;
            clock1_divide : natural := 1;
            clock0_settings : string := "UNUSED";
            clock1_settings : string := "UNUSED";
            outclock_phase_shift : natural := 0);
	port (inclock : in std_logic;
         inclocken : in std_logic;
         fbin : in std_logic := '0';
         clock0 : out std_logic;
         clock1: out std_logic;
         locked: out std_logic);
end component;
begin

rx_out    <= data_regs when registered_output = "ON" else data_int2;
rx_outclock <= rx_clkout_int;
rx_locked <= rx_locked_int;

U0: altclklock generic map (inclock_period => inclock_period,
                        clock0_boost => deserialization_factor)
           port map (inclock => rx_inclock, inclocken => en,
                     clock0 => rx_clkout_int, locked => rx_locked_int);

-- At start up deskew is done due to inability to detect unconnected rx_deskew
-- pin.
deskew: process(rx_deskew)
begin
   	if rx_deskew = '1' then
	   deskew_done <= (others => '0');
  	end if;
end process;


load_data: process(rx_clkout_int, rx_inclock)
variable rxin_cnt : integer := 0;
variable edge_count: integer := 0;
variable count: channel_cnt := (others => 0);
variable sample: integer;
variable start_data : integer := 0;
variable pattern, data_int: std_logic_vector(deserialization_factor*number_of_channels -1 downto 0);
begin
    if rx_inclock'event and rx_inclock = '1' then
      rxin_cnt := 0;
      if (deserialization_factor = 8)  then
         if (rx_deskew = '1') then
           for i in 0 to number_of_channels-1 loop
             if (pattern(((deserialization_factor*(i+1))-1) downto deserialization_factor*(i)) = "00001111") then
               count(i) := count(i) + 1;
             else
               count(i) := 0;
             end if;
             if count(i) = 3 then
                deskew_done(i) <= '1';
             end if;
           end loop;
         end if;
      elsif (deserialization_factor= 7) then
         if (rx_deskew = '1') then
           for i in 0 to number_of_channels-1 loop
             if (pattern(((deserialization_factor*(i+1))-1) downto deserialization_factor*(i)) = "0000111") then
               count(i) := count(i) + 1;
             else
               count(i) := 0;
             end if;
             if count(i) = 3 then
                deskew_done(i) <= '1';
             end if;
           end loop;
         end if;
      elsif (deserialization_factor= 4) then
         if (rx_deskew = '1') then
           for i in 0 to number_of_channels-1 loop
             if (pattern(((deserialization_factor*(i+1))-1) downto deserialization_factor*(i)) = "0011") then
               count(i) := count(i) + 1;
             else
               count(i) := 0;
             end if;
             if count(i) = 3 then
                deskew_done(i) <= '1';
             end if;
           end loop;
         end if;
      else
        deskew_done <= (others => '1');
      end if;
    elsif rx_clkout_int'event and rx_clkout_int = '0' then
       rxin_cnt := rxin_cnt + 1;
       if rxin_cnt = 3 then
         data_int2 <= data_int;
         start_data := 1;
      end if;
      if start_data = 1 then
       sample := edge_count rem deserialization_factor;
       edge_count := edge_count + 1;
       for i in 0 to number_of_channels -1 loop
         if deskew_done(i) = '1' then
           data_int((i*deserialization_factor)+sample) := rx_in(i);
         else
           pattern((i*deserialization_factor)+sample) := rx_in(i);
           data_int((i*deserialization_factor)+sample) := 'X';
         end if;
       end loop;
     end if;
    end if;
end process;


parallel_reg: process(rx_inclock)
begin
    if rx_inclock = '1' then
      if deserialization_factor = 8 or deserialization_factor = 7 then
        data_regs <= data_int2;
      else
        data_regs <= data_int3;
      end if;
    elsif rx_inclock = '0' then
      if deserialization_factor <= 4 then
        data_int3 <= data_int2;
      end if;
    end if;
end process parallel_reg;

end behavior;

-- lvds transmitter megafunction
--
    
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;

entity altlvds_tx is
    generic(
            number_of_channels: natural;
            deserialization_factor: natural;
            registered_input: string := "ON";
            multi_clock: string := "OFF";
            inclock_period: natural;
            clock_setting: string := "UNUSED");
    port (
			 tx_in: in std_logic_vector(deserialization_factor*number_of_channels -1 downto 0);
 			 tx_inclock: in std_logic;
          sync_inclock: in std_logic := '0';
          tx_out: out std_logic_vector(number_of_channels-1 downto 0);
          tx_outclock : out std_logic;
          tx_locked : out std_logic);
end altlvds_tx;

architecture behavior of altlvds_tx is
signal data_int, data_reg, tx_in_rgd: std_logic_vector(deserialization_factor*number_of_channels -1 downto 0);
signal clock_in: std_logic;
signal clock_out: std_logic; 
signal tx_locked_int: std_logic; 
signal en: std_logic := '1';
component altclklock
   generic (
            inclock_period : natural;
            inclock_settings : string := "UNUSED";
            valid_lock_cycles : natural := 3;
            invalid_lock_cycles : natural := 3;
            operation_mode : string := "NORMAL";
            clock0_boost : natural := 1;
            clock0_divide : natural := 1;
            clock1_boost : natural := 1;
            clock1_divide : natural := 1;
            clock0_settings : string := "UNUSED";
            clock1_settings : string := "UNUSED";
            outclock_phase_shift : natural := 0);
	port (inclock : in std_logic;
         inclocken : in std_logic;
         fbin : in std_logic := '0';
         clock0 : out std_logic;
         clock1: out std_logic;
         locked: out std_logic);
end component;
begin

data_int  <= data_reg when registered_input = "ON" else tx_in;
clock_in <= sync_inclock when multi_clock = "ON" else tx_inclock;
tx_outclock <= clock_out;
tx_locked <= tx_locked_int;

U0: altclklock generic map (inclock_period => inclock_period,
                     clock0_boost => deserialization_factor)
           port map (inclock => tx_inclock, inclocken => en,
                     clock0 => clock_out, locked => tx_locked_int);

serialize: process(clock_out, clock_in)
variable edge_count: integer;
variable load_data : std_logic := '0';
variable count: integer := 0;
variable sample: integer;
variable tx_in2: std_logic_vector(deserialization_factor*number_of_channels -1 downto 0);
begin
    if clock_in'event and clock_in = '1' then
       edge_count := 0;
    end if;
    if clock_out'event and clock_out = '1' then
       edge_count := edge_count + 1;
       if edge_count = 3 then
          tx_in2 := data_int; -- register the incoming data on the third edge
          count := 0;
          load_data := '1'; -- third_rising edge
       end if;
       if load_data = '1' then
         for i in 0 to number_of_channels-1 loop
           tx_out(i) <= tx_in2(i*deserialization_factor + count);
         end loop;
         count := count + 1;
       end if;
    end if;
end process;

sync: process(clock_in)
begin
    if clock_in = '0' then
      if deserialization_factor = 8 or deserialization_factor = 7 then
        data_reg <= tx_in_rgd;
      end if;
    elsif clock_in = '1' then
      if deserialization_factor <= 4 then
        data_reg <= tx_in;
      end if;
    end if;
end process sync;

end behavior;























⌨️ 快捷键说明

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