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

📄 usb_new_clkrec_rtl.vhdl

📁 usb rtl code, to fpga or asic
💻 VHDL
字号:
--------------------------------------------------------------------------------
---- File >>> usb_new_clkrec_rtl.vhdl 
---- Iden >>>							951017-16:10:26
----
---- Project:		USB Development
---- Customer:		Philips_ITCL
----
---- Module:		architecture RTL of entity CLKREC
---- Written by:	Jan Decaluwe (e-mail: jand@easics.be)
----			Easics nv
----			Kapeldreef 60
----			B-3001	Leuven
----			Belgium
----			Tel +32-16-270.400
----			Fax +32-16-270.319
----			e-mail: vhdl@easics.be
----
---- Creation Date:	Tue, 17 Oct 1995
----
---- Purpose:
----
---- Revision history:
----
--------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

library work;
use work.PCK_GENERAL.all;
use work.PCK_USB.all;

--  DESCRIPTION_BEGIN
--  The clock recovery generates a clock based on the transactions
--  on the Usb Bus (Dplus and Dmin). The recovered clock has a
--  rising edge in the middle of the bit on the Usb Bus.
--  DESCRIPTION_END

architecture RTL of CLKREC is

  signal UsbLineBits: two_bits;
  signal SyncCREN: booleans(2 downto 0);
  signal SyncD, SyncP, SyncN: two_bits;
  signal SyncSuspend: booleans(1 downto 0);
  signal DelayLineD, DelayLineP, DelayLineN: six_bits; 
  signal DelayLineSample: six_bits;
  signal Count: integer range 0 to 5;
  signal RefCount: integer range 0 to 3;
  signal Reduce, Extend, Rephase: boolean; 
  signal NegEdgeTime, EvalTime, PosEdgeTime, ExtendedPosEdgeTime: boolean;

begin


RECOVERY_PROCESS: process (Clk48MHz, Reset48MHz_N)

  begin

    if (Reset48MHz_N = ACTIVE_LOW) then

      SyncCREN <= (others => FALSE);
      SyncD <= (others => LOW); 
      SyncP <= (others => LOW); 
      SyncN <= (others => LOW); 
      SyncSuspend <= (others => FALSE);
      DelayLineD <= (others => HIGH);
      DelayLineP <= (others => HIGH);
      DelayLineN <= (others => LOW);
      DelayLineSample <= (others => HIGH);
      Count <= 0;
      RefCount <= 0;
      Reduce <= FALSE;
      Extend <= FALSE;
      RePhase <= FALSE;
      NegEdgeTime <= FALSE;
      EvalTime <= FALSE;
      PosEdgeTime <= FALSE;
      ExtendedPosEdgeTime <= FALSE;
      Clk12MHz_O <= LOW; 
      Clk12MHzRef_O <= LOW; 
      UsbLineBits <= (LOW, LOW); 

    elsif Clk48MHz'event and (Clk48MHz = '1') then

      EvalTime <= FALSE;

      -- DOC_BEGIN: Synchronizers and Delay Lines
      -- Warning: this implementation is biased towards high speed
      -- function clock recovery 
      -- A number of signals influencing the clock recovery come from
      -- the recovered clock domain. This causes problems with a synchronous
      -- reset strategy as in USBALB. To solve this generally, we will force
      -- these signals asynchronously to 0 during reset
      -- This is not a conceptual problem as these signals are treated
      -- in this module as asynchronous signals anyway: in other words,
      -- they are synchronized to the 48MHz clock before being used

      -- Synchronizer for Clock Recovery Enable from SIE module
      SyncCREN <= (SyncCREN(1), SyncCREN(0),
                   (SIE_CREnable and (PU_Reset_N = INACTIVE_HIGH)));

      -- Synchronizers for differential and single ended inputs
      SyncD <= (SyncD(0) , (HB_USBDifBit and PU_Reset_N)); 
      SyncP <= (SyncP(0) , (HB_USBLineBits(1) and PU_Reset_N)); 
      SyncN <= (SyncN(0) , (HB_USBLineBits(0) and PU_Reset_N)); 

      -- Synchronizer for Suspend from the Timers module
      SyncSuspend <= (SyncSuspend(0),
                      (TM_Suspend and (PU_Reset_N = INACTIVE_HIGH))); 

      -- Delay Line for the differential and single ended inputs
      DelayLineD <= DelayLineD(DelayLineD'high-1 downto 0) & SyncD(1); 
      DelayLineP <= DelayLineP(DelayLineP'high-1 downto 0) & SyncP(1); 
      DelayLineN <= DelayLineN(DelayLineN'high-1 downto 0) & SyncN(1); 
      -- DOC_END

      -- DOC_BEGIN: No Rephase during SE0
      -- Avoid rephase during SE0, during SE0 the RCV input is not well
      -- defined and can toggle causing rephase. This is not a problem,
      -- but is unwanted. It is solved by filling the DelayLineD that is
      -- used for rephase with the last value before SE0 was detected.
      -- This is done as long as SE0 is detected. SE0 is detected by
      -- looking at three values in the delay line of the single ended
      -- receivers.
      if (SyncP(1) = LOW)      and (SyncN(1) = LOW) and
         (DelayLineP(0) = LOW) and (DelayLineN(0) = LOW) and
         (DelayLineP(1) = LOW) and (DelayLineN(1) = LOW) then
        DelayLineD <= (others => DelayLineD(DelayLineD'high-1));
      end if;  
      -- DOC_END

      -- DOC_BEGIN: Generating the Recovered Clock
      -- The recovered clock is generated using a counter Count. The
      -- phase of this clock can be adjusted. When there is no
      -- activity on the Usb Bus, the recovered clock is free running
      -- on 12 MHz. When there is activity, the clock has to be
      -- rephased so that the rising edge is in the middle of the
      -- bit on the Usb Bus. Changing the phase is done by changing
      -- the way the counter Count is reset to 0. The counter can
      -- be reset to 0 at different times defined by the signals Reduce,
      -- Extend and Rephase.

      NegEdgeTime <= ((Count = 1) and Reduce) or
		     ((Count = 2) and (not (Reduce or Extend or Rephase))) or
		     ((Count = 3) and Extend) or
		     ((Count = 4) and Rephase);

      -- Reset the counter and take a sample of the delay line.
      -- Evaluation of this sample is used for rephasing (EvalTime).
      -- Recovered clock becomes LOW.

      if NegEdgeTime then
	Clk12MHz_O <= LOW; 
	Count <= 0;
	Reduce <= FALSE;
	Extend <= FALSE;
	Rephase <= FALSE;
	DelayLineSample <= DelayLineD; 
	EvalTime <= TRUE;
      else
	Count <= Count + 1;
      end if;

      -- The following code generates the HIGH period of the recovered
      -- clock. If there is a rephase, defined by Rephase, the clock
      -- stays high for one extra 48 MHz period. If this was not done,
      -- the clock would only stay HIGH for one 48 MHz period. This
      -- means an increase in frequency which is not allowed.

      PosEdgeTime <= (Count = 0);
      ExtendedPosEdgeTime <= (Count = 1);

      if PosEdgeTime and not Rephase then
	Clk12MHz_O <= HIGH; 
      end if;

      if ExtendedPosEdgeTime and Rephase then
	Clk12MHz_O <= HIGH; 
      end if;
      -- DOC_END

      -- DOC_BEGIN: Evaluation Delay Line Sample
      -- Reset delay line sample (on 'J') while not SyncCREN(1)  
      -- The goal is to prevent packets that are sent out to
      -- influence the clock recovery 

      if not SyncCREN(1) then
        DelayLineSample <= (others => HIGH);
      end if;

      -- The delay line sample is evaluated to decide what kind of
      -- rephasing is needed.
      -- Qualify eval time with SyncCREN(2) (consistent with reset above) 

      if EvalTime and SyncCREN(2) then 
	if    ( DelayLineSample(0) /= DelayLineSample(1) ) then
	  Extend <= TRUE; 
	elsif ( DelayLineSample(2) /= DelayLineSample(3) ) then
	  Reduce <= TRUE; 
	elsif ( DelayLineSample(3) /= DelayLineSample(4) ) then 
	  -- Out-of-phase error condition 
	  Rephase <= TRUE; 
	end if;
      end if;
      -- DOC_END

      -- DOC_BEGIN: Generate Dplus and Dmin for SIE
      -- Generation of clean DP and DM from incoming DP, DM and RCV
      -- in Suspend, take bus signals from single-ended receivers
      -- because differential receiver may be turned of

      if (SyncSuspend(1)) then
	UsbLineBits <= (DelayLineP(5), DelayLineN(5)); 
      elsif (two_bits'(DelayLineP(5), DelayLineN(5)) = two_bits'("00")) then
	UsbLineBits <= (LOW, LOW); 
      else
	UsbLineBits <= (DelayLineD(5), not DelayLineD(5));
      end if;
      -- DOC_END

      -- DOC_BEGIN: Reference Clock
      -- Free running 12 MHz reference clock.

      RefCount <= (RefCount + 1) mod 4;
      Clk12MHzRef_O <= conv_active_high(RefCount >= 2);       
      -- DOC_END
    end if;

  end process RECOVERY_PROCESS;

  -- recovered output data
  CR_UsbLineBits <= UsbLineBits;

  -- recovered output data for debug purposes 
  CR_DebugRecDataP <= UsbLineBits(1);
  CR_DebugRecDataN <= UsbLineBits(0);

end RTL;

⌨️ 快捷键说明

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