-- -----------------------------------------------------------
-- 
-- Additional material to the book
-- Modeling and Simulation for RF System Design
-- 
--
-- THIS MODEL IS LICENSED TO YOU "AS IT IS" AND WITH NO WARRANTIES, 
-- EXPRESSED OR IMPLIED. THE AUTHORS SPECIFICALLY DISCLAIM ALL IMPLIED 
-- WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-- THEY MUST NOT HAVE ANY RESPONSIBILITY FOR ANY DAMAGES, FINANCIAL OR
-- LEGAL CLAIMS WHATEVER.
-- -----------------------------------------------------------

-- Name:     Phase-frequency detector
-- 
-- Description:
-- This model describes a phase-frequency detector for use
-- as mixer in a digital PLL. The finite state machine is
-- implemented using pure VHDL.
-- 
--
-- Literature:
-- Best, R.: Phase-locked loops: design, simulation, and applications.
-- 5th edition, McGraw-Hill, 2003
-- 
--
-- Dependencies: 
-- -----------------------------------------------------------
-- Logical Library         Design unit
-- -----------------------------------------------------------
-- IEEE_proposed           ELECTRICAL_SYSTEMS
-- IEEE                    MATH_REAL
-- -----------------------------------------------------------
--
-- Source:
-- pfd.vhd
-- -----------------------------------------------------------

library IEEE, IEEE_proposed;                                            
  use IEEE_proposed.ELECTRICAL_SYSTEMS.all;
  use IEEE.MATH_REAL.all;

entity PFD is 
  generic (THD       : REAL := 2.5;   -- threshold value for a2d
           RIN       : REAL := 50.0);
  port (terminal P_CLK, P_REFCLK, GND: ELECTRICAL;
	signal S_UP, S_DOWN: out BIT:='0');    
end PFD;   

architecture A1 of PFD is

  --branch quantities
  quantity V_RIN1 across I_RIN1 through P_CLK to GND;
  quantity V_RIN2 across I_RIN2 through P_REFCLK to GND;

  signal STATE: INTEGER:=0;
  signal CLK, REFCLK: BIT:='0';

begin

  CLK <= '1' when V_RIN1'ABOVE(THD) else '0';
  REFCLK <= '1' when V_RIN2'ABOVE(THD) else '0';
  
  process (CLK,REFCLK)
    variable CLK_OLD, REFCLK_OLD: BIT:='0';
  begin
    case STATE is
      when -1 =>
	if REFCLK_OLD='0' and REFCLK='1' then
          STATE<=0;
        end if;
      when 0 =>
	if (REFCLK_OLD='0' and REFCLK='1') and not
	    (CLK_OLD='0' and CLK='1') then
	  STATE<=1;
        elsif (CLK_OLD='0' and CLK='1') and not
	  (REFCLK_OLD='0' and REFCLK='1') then
	  STATE<=-1;
        end if;
      when 1 =>
	if CLK_OLD='0' and CLK='1' then
	  STATE<=0;
        end if;
      when others => null;
    end case;
    CLK_OLD:=CLK;
    REFCLK_OLD:=REFCLK;
  end process;
  
  S_UP<='1' when STATE=1 else '0';
  S_DOWN<='1' when STATE=-1 else '0';
  V_RIN1 == RIN * I_RIN1;
  V_RIN2 == RIN * I_RIN2;

end architecture a1;                                            


