huoying 发表于 2024-3-27 08:43:26

问一个关于dpll的问题

在其他论坛上下了一个有问题的dpll程序,由于以前没有设计过pll,所以现在连port的意义及用处都不明白,所以想请各位介绍一下,谢谢。
程序如下:
Library ieee;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
entity dpll is
port(
    datain:   instd_logic;            -- raw data input
    clock:    instd_logic;            -- 64*bit clock
    rx_clock: out std_logic;            -- recovered rx clock
    dataout:out std_logic;            -- received data output
    clrdcd:   instd_logic;            -- clear dcd when 8 ones are detected in hdlcdec
    dcd:      out std_logic);         -- data carrier detect output
end dpll;
architecture behaviour of dpll is
signal counter: std_logic_vector(4 downto 0);   -- counter 0..31
signal dcd_cntr: std_logic_vector(5 downto 0);-- counter 0..127
signal edge: std_logic;                         -- edge detector output: data decision changed
signal dly_data: std_logic;                     -- delayed data for edge detector
signal ql: std_logic;                           -- late clock
signal qe: std_logic;                           -- early clock
signal enable: std_logic;                     -- gets toggled every clock or when clock has to be adjusted
signal increment: std_logic;
signal decrement: std_logic;
signal clear_dcd: std_logic;
signal reset_dcd: std_logic;
begin
--
-- recovered rx clock for followning stages
--
rx_clock <= counter(4);
process(clock,clrdcd,reset_dcd)
begin
if (clock'event and clock='1' ) then
    clear_dcd <= reset_dcd or clrdcd;
end if;
end process;
--
-- clock in new data
--
process(clock,datain)
begin
if (clock'event and clock='1' ) then
    dataout <= datain;
end if;
end process;
--
-- rx clock counter
--
process(clock,enable,clrdcd)
begin
--if ( clrdcd='1') then                      -- reset for illegal data at hdlcdec
--    counter <= (others => '0');
if (clock'event and clock='1' ) then
    if (enable='1') then
      counter <= counter+1;                  -- increase counter
    else
      counter <= counter;   
    end if;
end if;
end process;
--
-- set early and late clocks
--
process(counter)
begin
if (counter="10000" or counter ="01111" ) then
    ql <= '0';
    qe <= '0';
elsif (counter(4)='1') then-- late clock when counter > 32
    ql <= '1';
    qe <= '0';
else
    ql <= '0';               -- early clock when counter < 31
    qe <= '1';
end if;
end process;
--
-- adjst rx clock
-- this is done by changing the enable signal for the rx clock counter
-- enable gets toggled every clock event. It gets set additionally when
-- the clock counter should be incremented and cleared when clock should
-- be decremented.
--
process(clock,enable,clrdcd)
begin
--if ( clrdcd='1') then
--    enable<='0';
--    increment <='0';
--    decrement <='0';
if (clock'event and clock='1') then
    if (qe='1' and edge='1') then
      increment <='1';                      -- increment clock when edge detect
    end if;                                 -- during early clock
    if (ql='1' and edge='1') then
      decrement <='1';                      -- decrement clock when edge detect
    end if;                                 -- during late clock
    if (enable ='1') then
      if (increment ='1') then
      increment <='0';                  -- clear after one increment step
      enable <='1';
      else
      enable <='0';
      end if;
    else
      if (decrement ='1') then
      decrement<='0';                     -- clear after one decrement step
      enable <= '0';
      else
      enable <='1';      
      end if;
    end if;
end if;
end process;
--
-- dcd detection
--
process(clock,edge,counter,clear_dcd)
begin
if ( clear_dcd='1') then
    dcd_cntr<= (others => '0');   
    dcd <= '0';
    reset_dcd <='0';
elsif (counter(4)'event and counter(4)='0') then
    if ( edge='0' ) then                  -- sample at rising edge, if no data change increase counter
      if (dcd_cntr = 63) then
      dcd <= '1';                         -- assert dcd if dcd counter is at max
      dcd_cntr <= dcd_cntr;
      else
      dcd <= '0';
      dcd_cntr <= dcd_cntr+1;
      end if;      
    else
      reset_dcd <='1';
    end if;
end if;
end process;
--
-- edge detector, input data has changed
--
process(clock,datain)
begin
    if (clock'event and clock='1') then
      edge <= dly_data xor datain;
      dly_data <= datain;
    end if;
end process;
end behaviour;
页: [1]
查看完整版本: 问一个关于dpll的问题