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

📄 usb_new_rgen_rtl.vhdl

📁 实现USB接口功能的VHDL和verilog完整源代码
💻 VHDL
字号:
--------------------------------------------------------------------------------
---- File >>> usb_new_rgen_rtl.vhdl 
---- Iden >>>							951124-17:36:08
----
---- Project:		USB Development
---- Customer:		Philips_ITCL
----
---- Module:		architecture RTL of entity RGEN
---- 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:	Fri, 24 Nov 1995
----
---- Purpose:
----
---- Revision history:
----
--------------------------------------------------------------------------------
-- DESCRIPTION_BEGIN
-- This module makes all the reset signals ultimately based on the USB bus
-- and power on reset.
-- DESCRIPTION_END

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;

architecture RTL of RGEN is
 
  signal BUSReset_N: one_bit;
  signal BUSReset_N_Z1: one_bit;
  signal BUSReset_N_Z2: one_bit;
  signal PUReset_N_int: one_bit;

  signal Reset48Mhz_N_S1: one_bit;
  signal Reset48Mhz_N_S2: one_bit;

  signal Reset12Mhz_N_S1: one_bit;
  signal Reset12Mhz_N_S2: one_bit;

  signal Reset12MhzRef_N_S1: one_bit;
  signal Reset12MhzRef_N_S2: one_bit;

  signal PUorBUSReset12MHz_N: one_bit;

  signal SE0Detect: boolean;
  signal SE0Detect_S1: boolean;
  signal SE0Detect_S2: boolean;

  signal UP_DsLogValue: T_UsbLog_enum;

  signal USB_Reset_O_N_int: one_bit;
begin

----------------------------------------------------------
------------        Reset for 48 MHz       ---------------
----------------------------------------------------------

RESET_48MHz: process(PU_Reset_N, Clk48Mhz)
begin

-- DOC_BEGIN: Reset for 48 MHz  
-- Introduce 2 synchronisation
-- flip flops
-- for 48 MHz domain
  
 if PU_Reset_N = ACTIVE_LOW then
   Reset48MHz_N_S1 <= ACTIVE_LOW;
   Reset48MHz_N_S2 <= ACTIVE_LOW;
   
 elsif (Clk48Mhz'event and Clk48Mhz = '1') then
   Reset48MHz_N_S1 <= PU_Reset_N;
   Reset48MHz_N_S2 <= Reset48Mhz_N_S1;
 end if;

--DOC_END
 
end process;

Reset48MHz_N <= PU_Reset_N when (TestMode = '1') else
		Reset48Mhz_N_S2;



----------------------------------------------------------
----------    Reset for 12 MHz reference     -------------
----------------------------------------------------------

RESET_12MHzRef: process(PU_Reset_N, Clk12MhzRef)
begin
  
-- DOC_BEGIN: Reset for 12 MHz reference
-- Introduce 2 synchronisation flip flops
-- for 12 MHz reference domain
  
 if PU_Reset_N = ACTIVE_LOW then
   Reset12MhzRef_N_S1 <= ACTIVE_LOW;
   Reset12MhzRef_N_S2 <= ACTIVE_LOW;
 elsif (Clk12MhzRef'event and Clk12MhzRef = '1') then
   Reset12MhzRef_N_S1 <= PU_Reset_N;
   Reset12MhzRef_N_S2 <= Reset12MhzRef_N_S1;
 end if;
 
--DOC_END
 
end process;

Reset12MhzRef_N <= PU_Reset_N when (TestMode = '1') else
		   Reset12MhzRef_N_S2;


----------------------------------------------------------
----------    Reset for 12 MHz recovered     -------------
----------------------------------------------------------

RESET12MHzRef: process(PU_Reset_N, FsClk)

-- DOC_BEGIN: Reset for 12 MHz recovered 
-- Introduce 2 synchronisation flip flops
-- for 12 MHz recovered domain
  
begin
 if PU_Reset_N = ACTIVE_LOW then
   Reset12Mhz_N_S1 <= ACTIVE_LOW;
   Reset12Mhz_N_S2 <= ACTIVE_LOW;
 elsif (FsClk'event and FsClk = '1') then
   Reset12Mhz_N_S1 <= PU_Reset_N;
   Reset12Mhz_N_S2 <= Reset12Mhz_N_S1;
 end if;
end process;

-- DOC_END

PUReset_N_int <= PU_Reset_N when (TestMode = '1') else
		 Reset12Mhz_N_S2;
PUReset_N <= PUReset_N_int;


----------------------------------------------------------
----------  Bus Reset for 12 MHz recovered   -------------
----------------------------------------------------------

-- DOC_BEGIN: Bus Reset for 12 MHz recovered
-- Give a reset when Power up reset or bus reset.
PUorBUSReset12MHz_N <= conv_active_low(
			 BUSReset_N = ACTIVE_LOW or
                         Reset12Mhz_N_S2 = ACTIVE_LOW);

Reset_N <= PU_Reset_N when (TestMode = '1') else
	     PUorBUSReset12Mhz_N;
-- DOC_END

----------------------------------------------------------
----------       Interrupt generator         -------------
----------------------------------------------------------


INT_GEN: process(PUReset_N_int, FsClk)
begin
-- DOC_BEGIN
-- Insert two delay flip flops
-- to introduce edge detection
  
  if PUReset_N_int = ACTIVE_LOW then
    BUSReset_N_Z1 <= HIGH;
    BUSReset_N_Z2 <= HIGH;
    RG_SetSE0Int <= FALSE;
  elsif (FsClk'event and FsClk = '1') then
    BUSReset_N_Z1 <= BUSReset_N;
    BUSReset_N_Z2 <= BUSReset_N_Z1;
    
    -- detect rising edge, active low to active high
    -- on bus reset line 
    -- to make pulse on RG_SetSE0Int
    
    RG_SetSE0Int <= (BUSReset_N_Z2 = ACTIVE_LOW and
		     BUSReset_N_Z1 = INACTIVE_HIGH);
  end if;
end process;
-- DOC_END

----------------------------------------------------------
----------       Bus Reset Detector          -------------
----------------------------------------------------------

-- DOC_BEGIN: Bus SE0 Detector 
-- Convert
-- the incoming UP bits
-- to a logical representation

UP_DsLogValue <= UsbDif2Log(UP_DsLineBits, USB_FULL_SPEED);
SE0Detect <= (Up_DsLogValue = USB_LOG_SE0);
-- DOC_END

USB_Reset_O_N <= USB_Reset_O_N_int;
  
BUSRESET_DETECT: process(PUReset_N_int, FsClk)
  constant RESET_TIMER_RANGE: integer := 64;
  constant RESET_DETECT_TIME: integer := 48;

  variable BusResetTimer: integer range 0 to RESET_TIMER_RANGE-1;
begin
  if (PUReset_N_int = ACTIVE_LOW) then
    BusResetTimer := 0;
    BUSReset_N <= INACTIVE_HIGH;
    SE0Detect_S1 <= FALSE;
    SE0Detect_S2 <= FALSE;
    USB_Reset_O_N_int <= INACTIVE_HIGH;
    
  elsif (FsClk'event and FsClk = '1') then

    -- defaults
    USB_Reset_O_N_int <= INACTIVE_HIGH;
    
    -- DOC_BEGIN:  Bus reset pulse generation (delay and extention)
    
    -- As long as there is no SE0, BusResetTimer stays at 0.
    -- Mind that the Inc(rement) part in IncSat() makes BusResetTimer overflow
    -- when it is incremented by 1 from RESET_TIMER_RANGE-1
    -- The Sat(uration) part in IncSat() also keeps it at 0.
    
    BusResetTimer := IncSat(BusResetTimer , RESET_TIMER_RANGE);
    
    -- When there is an SE0, BusResetTimer starts counting. If there is 
    -- 1 cycle of non-SE0, it is reset to 0.
    -- Up to 48 BUSReset_N is INACTIVE_HIGH.
    
    if (BusResetTimer < RESET_DETECT_TIME) then
      BUSReset_N <= INACTIVE_HIGH;
      if (not SE0Detect_S2) then 
	BusResetTimer := 0;
      end if;
      
    -- When BusResetTimer reaches 48 (about 4 us), BUSReset_N goes ACTIVE_LOW
    -- and BusResetTimer keeps counting, even if there is no SE0
    -- anymore on the bus.
      
    elsif (BusResetTimer < RESET_TIMER_RANGE-1) then
      BUSReset_N <= ACTIVE_LOW;
      
    -- When the timer reaches 63, BusReset_N goes INACTIVE_HIGH again.
    -- The timer stays at 63 until the SE0 ends.
    -- This guarantees a reset pulse with a fixed width.
      
    else
      BUSReset_N <= INACTIVE_HIGH;
      USB_Reset_O_N_int <= ACTIVE_LOW;
      if (not SE0Detect_S2) then 
	BusResetTimer := 0;
      end if;
    end if;

    SE0Detect_S1 <= SE0Detect;
    SE0Detect_S2 <= SE0Detect_S1;
    -- DOC_END

    
  end if;

end process;

  RG_BUSReset <= (BUSReset_N = ACTIVE_LOW);

  -- bus active signal
  RG_BusActive <=
    (UsbDif2Log(UP_DsLineBits, GetDeviceSpeed(ConfigArray)) /= USB_LOG_J);

end RTL;

⌨️ 快捷键说明

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