📄 pll_si.vhd
字号:
------------------------------------------------------------------------------
-- *** Disclaimer: This example code is provided with no support. ***
------------------------------------------------------------------------------
-- File : pll_si.vhd
-- Author : Shraddha
-- Created :
-- Last modified : April 24, 2003
-- Project : OSD FPGA
------------------------------------------------------------------------------
-- Description : Writes to the PLL on EVM using Serial interface
--
------------------------------------------------------------------------------
-- Modification history :
-- Jan 31, 2003 : Shraddha : created
-- April 24, 2003 : Shraddha: Added soft reset to the PLL SI module
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity PLL_SI is
port (
-- from Power Supply
RESETz : in std_logic; -- System Reset
SRESETz : in std_logic; -- Soft Reset
-- Clock
EMIF_CLK : in std_logic; -- EMIF Clock
-- From/to Registers
TX_DATA : in std_logic_vector(15 downto 0); -- PLL config data
TX_START : in std_logic; -- Transmit start indicator
PLL_TX_END : out std_logic; -- Transmit End indicator
-- Output to PLL
PLL_MC : out std_logic; -- PLL Serial clock
PLL_MD : out std_logic; -- PLL Serial Data
PLL_MS : out std_logic -- PLL Select
);
end PLL_SI;
architecture RTL of PLL_SI is
signal CLOCK_TICK : std_logic; -- Clock tick for every 10 EMIF clocks
signal CLK_COUNTER : std_logic_vector(3 downto 0); -- Counts clocks
signal BIT_COUNT : std_logic_vector(3 downto 0); -- Tracks bit count
signal DATA_SR : std_logic_vector(15 downto 0); -- Data shift register
signal P_PLL_MS : std_logic;
signal P_PLL_MD : std_logic;
signal P_PLL_MC : std_logic;
signal LAST_BIT : std_logic;
type SI_TYPE is
(
IDLE, -- sm idles here
INITIALIZE, -- the pll_si is initialized
TX_FALLING_EDGE, -- falling edge of clock
TX_RISING_EDGE, -- rising edge of clock
TX_END -- transmision ends here
);
signal SI_STATE : SI_TYPE;
begin -- RTL
-- purpose: generates clock tick for every 10 EMIF clocks. This allows us
-- to transmit data to the PLL at 1/10th the EMIF speed.
CLK_TICK: process (EMIF_CLK, RESETz)
begin -- process CLK_TICK
if RESETz = '0' or SRESETz = '0' then -- asynchronous reset (active low)
CLOCK_TICK <= '0';
CLK_COUNTER <= "0000";
elsif EMIF_CLK'event and EMIF_CLK = '1' then -- rising clock edge
if CLK_COUNTER = "1010" then
CLK_COUNTER <= "0000";
CLOCK_TICK <= '1';
else
CLK_COUNTER <= CLK_COUNTER + 1;
CLOCK_TICK <= '0';
end if;
end if;
end process CLK_TICK;
-- purpose: Serial Interface State Machine
SI_SM: process (EMIF_CLK, RESETz)
begin -- process SI_SM
if RESETz = '0' or SRESETz = '0' then -- asynchronous reset (active low)
SI_STATE <= IDLE;
BIT_COUNT <= "1111";
P_PLL_MS <= '1';
P_PLL_MC <= '0';
P_PLL_MD <= '0';
LAST_BIT <= '0';
DATA_SR <= (others => '0');
PLL_TX_END <= '0';
elsif EMIF_CLK'event and EMIF_CLK = '1' then -- rising clock edge
PLL_TX_END <= '0';
case SI_STATE is
when IDLE =>
-- state machine idles here. All the output signals are held at
-- steady state.
P_PLL_MS <= '1';
P_PLL_MC <= '0';
P_PLL_MD <= '0';
LAST_BIT <= '0';
DATA_SR <= (others => '0');
-- when TX_START is set, the sm moves to INITIALIZE.
if TX_START = '1' then
SI_STATE <= INITIALIZE;
else
SI_STATE <= IDLE;
end if;
when INITIALIZE =>
-- Counters are initialized, and the output signals are held at
-- steady state. Data to be transmitted is moved to data shift
-- register DATA_SR.
P_PLL_MS <= '1';
P_PLL_MC <= '0';
P_PLL_MD <= '0';
DATA_SR <= TX_DATA;
-- Next state is always the falling edge state.
SI_STATE <= TX_FALLING_EDGE;
BIT_COUNT <= "1111";
LAST_BIT <= '0';
when TX_FALLING_EDGE =>
if CLOCK_TICK = '1' then
-- This logic here checks whether all the data bits have been
-- transmitted. When BIT_COUNT is zero, the current bit is the
-- last bit left.
if BIT_COUNT = "0000" then
LAST_BIT <= '1';
else
LAST_BIT <= '0';
end if;
P_PLL_MS <= '0';
P_PLL_MC <= '0';
BIT_COUNT <= BIT_COUNT - 1;
-- if last bit is detected, the sm moves to TX_END, otherwise it
-- goes to the rising edge state. The data is shifted out with
-- the falling edge of the clock.
if LAST_BIT = '1' then
SI_STATE <= TX_END;
P_PLL_MD <= '0';
else
SI_STATE <= TX_RISING_EDGE;
P_PLL_MD <= DATA_SR(conv_integer(BIT_COUNT));
end if;
else
P_PLL_MS <= P_PLL_MS;
P_PLL_MC <= P_PLL_MC;
P_PLL_MD <= P_PLL_MD;
SI_STATE <= TX_FALLING_EDGE;
end if;
DATA_SR <= DATA_SR;
when TX_RISING_EDGE =>
-- Here the value on the data pin is held. Next state is falling
-- edge state provided CLOCK_TICK is '1'.
if CLOCK_TICK = '1' then
P_PLL_MS <= P_PLL_MS;
P_PLL_MC <= '1';
P_PLL_MD <= P_PLL_MD;
SI_STATE <= TX_FALLING_EDGE;
else
P_PLL_MS <= P_PLL_MS;
P_PLL_MC <= P_PLL_MC;
P_PLL_MD <= P_PLL_MD;
SI_STATE <= TX_RISING_EDGE;
end if;
DATA_SR <= DATA_SR;
LAST_BIT <= LAST_BIT;
when TX_END =>
-- Transmission has ended here. The signals are set to their
-- steady states when CLOCK_TICK is '1' and the next state is
-- idle. The PLL_TX_END flag is set in this state.
if CLOCK_TICK = '1' then
P_PLL_MS <= '1';
P_PLL_MC <= '0';
P_PLL_MD <= '0';
SI_STATE <= IDLE;
PLL_TX_END <= '1';
else
P_PLL_MS <= P_PLL_MS;
P_PLL_MC <= P_PLL_MC;
P_PLL_MD <= P_PLL_MD;
SI_STATE <= TX_END;
PLL_TX_END <= '0';
end if;
DATA_SR <= DATA_SR;
LAST_BIT <= LAST_BIT;
when others => null;
end case;
end if;
end process SI_SM;
PLL_MS <= P_PLL_MS;
PLL_MD <= P_PLL_MD;
PLL_MC <= P_PLL_MC;
end RTL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -