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

📄 usb_new_timers_sf_rtl.vhdl

📁 实现USB接口功能的VHDL和verilog完整源代码
💻 VHDL
字号:
---------------------------------------------------------------------------------
---- File >>> usb_new_timers_sf_rtl.vhdl 
---- Iden >>>							970604-14:16:12
----
---- Project:		USB Development
---- Customer:		Philips_ITCL
----
---- Module:		architecture RTL of entity TIMERS_SF
---- Written by:	Usb User (e-mail: usb@easics.be)
----			Easics nv
----			Kapeldreef 60
----			B-3001	Leuven
----			Belgium
----			Tel +32-16-298.400
----			Fax +32-16-298.319
----			e-mail: vhdl@easics.be
----
---- Creation Date:	Wed, 04 Jun 1997
----
---- Purpose:
----
---- Revision history:
----
---------------------------------------------------------------------------------
--  DESCRIPTION_BEGIN
--  The TIMERS_SF module (SF stands for Single Function) generates
--  a 1 kHz clock based on the Start Of Frame packets. The 1 kHz
--  clock (Frame Clock) is used for slow timers (several milliseconds) and for
--  toggling the buffers for isochronous endpoints.
--  The TIMERS_SF module is responsible for timing during resume and
--  suspend. It also controls the clock while the device goes in suspend
--  or starts resuming.
--  DESCRIPTION_END

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

--library LIB_PACKAGES;
--use LIB_PACKAGES.PCK_GENERAL.all;
--use LIB_PACKAGES.PCK_SETUP.all;
--use LIB_PACKAGES.PCK_USB.all;

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

architecture RTL of TIMERS_SF is

  constant SUSPEND_TIME: integer := 3;
  constant IDLE_BEFORE_RESUME_TIME: integer := 5;
  constant RESUME_TIME: integer := 3;
  constant CLOCK_OFF_DELAY: integer := 7;

  type T_SR_State is (IDLE, SENDING);

  signal Clk1kHz: boolean; 
  signal Clk1kHzPulse: boolean;

  signal DeviceSuspended: boolean;
  signal Suspend5ms: boolean;

  signal ClockOnTimer: integer range 0 to CLOCK_OFF_DELAY;
  signal ClockOn: one_bit;
  signal Needclock: boolean;
  signal ClockIsOff: boolean;

  constant MAX_FRAME_LENGTH:integer := GetFrameLength(MAX_DEVICE_SPEED);
  signal FrameTimer: integer range 0 to MAX_FRAME_LENGTH;
  signal FrameLength: integer range 0 to MAX_FRAME_LENGTH;
  signal HalfWay: integer range 0 to MAX_FRAME_LENGTH/2;
  signal ISOToggle: integer range 0 to 1;
  signal Clk1kHz_Z: boolean; 

begin


  -- Device Speed is supposed not to change during normal
  -- operation
  FrameLength <= GetFrameLength(GetDeviceSpeed(ConfigArray));
  HalfWay <= FrameLength /2;
  TM_IsoToggle <= ISOToggle;
-----------------------------------------------------------------------
--                             FrameTimer                            --
-----------------------------------------------------------------------

 
MAIN: process (FsClk, PUReset_N)
  
  variable SOF: boolean;
	 
  variable ResumeTimer: integer range 0 to SUSPEND_TIME;
  variable SR_State: T_SR_State;
  variable ResumePending: boolean;
  variable RG_BusActive_S: boolean;
  variable SuspendTimer: integer range 0 to IDLE_BEFORE_RESUME_TIME;

  variable NeedClock_S: boolean;
  variable ClockIsOff_S: boolean;
  variable ClockIsOff_SS: boolean;
  variable RxSOF_Z: boolean;

  variable RemoteWakeup_S: boolean;
  variable RemoteWakeup_SS: boolean;

begin
	     
  if (PUReset_N = ACTIVE_LOW) then
		
    FrameTimer <= 0;
    RxSOF_Z := FALSE;
    Clk1kHz <= FALSE;
    Clk1kHz_Z <= FALSE;
    Clk1kHzPulse <= FALSE;
								     
    ResumeTimer := 0;
    SR_State := IDLE;
    TM_SendResume <= FALSE;
    ResumePending := FALSE;
    RG_BusActive_S := FALSE;

    SuspendTimer := 0;
    DeviceSuspended <= FALSE;
    Suspend5ms <= FALSE;
    TM_RemoteWakeUpEvent <= FALSE;

    ClockOnTimer <= 0;
    NeedClock_S := TRUE;
    ClockIsOff_S := FALSE;
    ClockIsOff_SS := FALSE;
    TM_ClockRestarted <= FALSE;
    if SUPPORT_ISO then
      ISOToggle <= 0;
    end if;

    RemoteWakeup_S :=  FALSE;
    RemoteWakeup_SS := FALSE;

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

----------------------------------------------------------
--                       Bus reset                      --
----------------------------------------------------------
    if RG_SetSE0Int then
      ResumeTimer := 0;
      TM_SendResume <= FALSE;
      ResumePending := FALSE;
      SuspendTimer := 0;
      DeviceSuspended <= FALSE;
      Suspend5ms <= FALSE;
    end if;

----------------------------------------------------------
--         1 kHz Clock and pulse generator              --
----------------------------------------------------------
    -- DOC_BEGIN: 1kHz Clock Generator
    -- The frame timer circuit generates a 50% duty cycle frame 
    -- clock (1 kHz) and a one cycle pulse on every rising edge
    -- of the frame clock. This pulse is used by a number of  
    -- millisecond timers in this and other modules. The timer
    -- is synchronized to the Start of Frame packets in a way
    -- the rising edge of the clock occurs in the middle of the 
    -- SOF packet. If there are no SOF's (this is always the
    -- case for low speed devices), the timer is free running.

					    
    Clk1kHz <= (FrameTimer < HalfWay);
    Clk1kHzPulse <= IsRisingEdge(Clk1kHz, Clk1kHz_Z);
    Clk1kHz_Z <= Clk1kHz;

    -- set SOF when RxSOF detected
    SOF := IsRisingEdge(SIE_RxSOF,RxSOF_Z);
    RxSOF_Z := SIE_RxSOF;

    if (Clk1kHz and not Clk1kHz_Z) then
      if SUPPORT_ISO then
        ISOToggle <= 1 - ISOToggle;
      end if;
    end if;


    if SOF or (FrameTimer = FrameLength-1) then
      FrameTimer <= 0;
    else
      FrameTimer <= FrameTimer +1;
    end if; 
								      
    -- DOC_END


-----------------------------------------------------------
--                 Resume Timers                         --
-----------------------------------------------------------

    -- DOC_BEGIN: Resume Timing
    -- The resume timer controls the generation of a remote
    -- wake up. The remote wake-up can be requested by the
    -- micro-controller or by making the external input
    -- RemoteWakeup active.
    --
    -- If remote wake-up is requested then this request is
    -- queued until the bus has been idle for 5 ms.
    -- At that moment, an upstream wake up is generated
    -- for 3 ms. If any bus activity occurs before the 5 ms
    -- of idle bus, the request is discarded.

    TM_SendResume <= FALSE;
    if (RG_BusActive_S) then
      ResumePending := FALSE;
    end if;

    case SR_STATE is

      when IDLE =>
	ResumeTimer := 0;
	if MM_Resume or
           (RemoteWakeup_SS and RemoteWakeUpEnable(ConfigArray)) then 
	  ResumePending := TRUE;
	  TM_RemoteWakeUpEvent <= RemoteWakeup_SS and
                                  RemoteWakeUpEnable(ConfigArray);
        end if;
	if (ResumePending and Suspend5ms) then 
	  SR_State := SENDING;
	end if;


      when SENDING =>
	TM_SendResume <= TRUE;
	if Clk1kHzPulse then
	  if (ResumeTimer = RESUME_TIME) then 
	    SR_State := IDLE;
            TM_RemoteWakeUpEvent <= FALSE;
	  end if;
	  ResumeTimer := IncSat(ResumeTimer, RESUME_TIME +1);
	end if;

    end case;
    -- DOC_END


-----------------------------------------------------------
--                 Suspend Timers                        --
-----------------------------------------------------------

    -- DOC_BEGIN: Awake/Suspend Control
    -- The suspend timer controls the suspend/awake behavior. 
    -- There are 3 states: awake, suspended and an intermediate 
    -- state. A device is awake if there has been bus activity
    -- in the last 3 ms. A device is suspended (the low power
    -- state) when it hasn't seen any traffic for at least 5 ms.
    -- Between 3 and 5 ms there is an intermediate state during
    -- which the device prepares itself to go into the suspended
    -- state


    if RG_BusActive_S then
      SuspendTimer := 0;
      DeviceSuspended <= FALSE;
      Suspend5ms <= FALSE;
    elsif Clk1kHzPulse then
      DeviceSuspended <= (SuspendTimer >= SUSPEND_TIME);
      Suspend5ms <= (SuspendTimer = IDLE_BEFORE_RESUME_TIME);
      SuspendTimer := IncSat(SuspendTimer,IDLE_BEFORE_RESUME_TIME+1);
    end if;

    -- DOC_END

-----------------------------------------------------------
--                 ClockOnTimer                          --
-----------------------------------------------------------

    -- DOC_BEGIN: Clock Control
    -- The clock timer controls the minimum time diring which
    -- the clock is switched on for devices that switch their
    -- clock off when they are suspended. This timer is reset
    -- whenever the clock goes on, and the clock can only go 
    -- off when this timer reaches its maximum.


    if NeedClock_S or (ClockIsOff_SS and (not ClockIsOff_S)) then
      ClockOnTimer <= 0;
    else
      ClockOnTimer <= IncSat(ClockOnTimer,CLOCK_OFF_DELAY+1);
    end if;

    -- DOC_END

    NeedClock_S := NeedClock;
    TM_ClockRestarted <= (ClockIsOff_SS and (not ClockIsOff_S));
    ClockIsOff_SS := ClockIsOff_S;
    ClockIsOff_S := ClockIsOff;
    RG_BusActive_S := RG_BusActive;

    RemoteWakeup_SS := RemoteWakeup_S;
    RemoteWakeup_S :=  RemoteWakeup;

  end if;

end process MAIN;



NeedClock <= MM_NeedCLock or PI_NeedCLock or EX_NeedClock or 
	     (not Suspend5ms) or RG_BusActive or (not Suspend_In) or
	     PUReset_N = ACTIVE_LOW or AlwaysPLLClock(ConfigArray) or
             RemoteWakeup;

    -- DOC_BEGIN
    -- The clock control block controls the switching of the clock.
    -- It consists of two asynchronous flip flops. Whenever a clock
    -- is needed (NeedClock = TRUE), the first flip flop is set. The
    -- output of this flip flop controls the clock. It is reset
    -- asynchronously when the clock timer reaches its maximum value,
    -- which can only happen if no clock is needed.
    -- The second flip flop is used to reset the clock timer. when the
    -- output of the first flip flop goes low, it is reset 
    -- asynchronously. When the clock restarts, the flip flop is
    -- reset synchronously, and the output of the flip flop is
    -- clocked into a delay line. The rising edge in the delay line
    -- causes the clock timer to be reset

CLOCK_ON: process(PUReset_N,FsClk,NeedClock,TestMode)
begin
  if (PUReset_N = ACTIVE_LOW) or (NeedClock and TestMode = '0') then
    ClockOn <= '1';
  elsif FsClk'event and FsClk = '1' then
    if ClockOnTimer = CLOCK_OFF_DELAY-1 then
      ClockOn <= '0';
    end if;
  end if;
end process CLOCK_ON;

CLOCK_IS_OFF: process(PUReset_N,FsClk,ClockOn,TestMode)
begin
  if (PUReset_N = ACTIVE_LOW) or (ClockOn = '0' and Testmode = '0') then
    ClockIsOff <= FALSE;
  elsif FsClk'event and FsClk = '1' then
    ClockIsOff <= (ClockOn = '0');
  end if;
end process CLOCK_IS_OFF;

    -- DOC_END

TM_ClockOn <= ClockOn;

USB_Suspended <= conv_active_high(DeviceSuspended);
TM_Suspend <= DeviceSuspended;
TM_Idle5ms <= Suspend5ms;


USB_FrameClock <= conv_active_high(Clk1kHz);
TM_1kHzPulse <= conv_active_high(Clk1kHzPulse);

TM_EOF1 <= FALSE;
TM_EOF2 <= FALSE;

end RTL;

⌨️ 快捷键说明

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