------------------------------------------------------------------------------------ -- $Archive:: /VHDL/product/dsk5509/cntl_cpld/cntlcpld.vhd $ -- $Revision:: 1 $ -- $Date:: 11/09/05 7:01a $ -- $Author:: Tonyc $ -- -- -- ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------ -- Start the real code ------------------------------------------------------------------------------------ library IEEE; use IEEE.std_logic_1164.all; -- -- -- entity cntlcpld is port ( CLKIN : in std_logic; -- 20 MHz clock in PONRSn : in std_logic; -- Power on reset from voltage supervisor PON_CORE : in std_logic; -- Core Power Status PUSHBRS : in std_logic; -- Push button reset USB_DSP_RS : in std_logic; USB_PORSTn : out std_logic; -- DSP Memory interface signals DSP_DQ : inout std_logic_vector( 7 downto 0 ); -- DSP Data bus DSP_ADDR : in std_logic_vector( 4 downto 1 ); -- DSP Address bus DSP_ADDR20 : in std_logic; -- Upper DSP Address DSP_ADDR19 : in std_logic; DSP_ADDR18 : in std_logic; DSP_ADDR17 : in std_logic; -- DSP Control strobes DSP_WEn : in std_logic; -- DSP Write strobe DSP_REn : in std_logic; -- DSP Read strobe DSP_OEn : in std_logic; -- DSP Output enable -- DSP Reset DSP_RSn : out std_logic; -- DSP Reset DSP_RS_LEDn : out std_logic; -- DSP Reset LED FLASH_CEn : out std_logic; FLASH_RSn : out std_logic; -- DSP Memory Chip Select signals DSP_CS3n : in std_logic; -- DSP DC Chip select DSP_CS2n : in std_logic; -- DSP DC Chip Select 2 DSP_CS1n : in std_logic; -- Flash Chip Select 2 -- DSP GPIO Lines DSP_GP6 : in std_logic; DSP_GP5 : in std_logic; DSP_TINOUT_0: inout std_logic; DSP_INT0 : out std_logic; DSP_INT1 : out std_logic; DSP_INT3 : out std_logic; -- User/Board Support USER_SW : in std_logic_vector( 3 downto 0 ); USER_LED : out std_logic_vector( 3 downto 0 ); -- Daughter Card Support DC_STAT : in std_logic_vector( 1 downto 0 ); -- DC Status DC_CNTL : out std_logic_vector( 1 downto 0 ); -- DC Control DC_DETn : in std_logic; -- DC Detect DC_POR : in std_logic; DC_RESETn : out std_logic; -- DC Reset DC_DBUF_OEn : out std_logic; -- DC Data buffer output enable DC_CNTL_OEn : out std_logic; -- DC Control buffer enable DC_DBUF_DIR : out std_logic; X_TIN0 : in std_logic; X_TOUT0 : inout std_logic; -- Daughter Card Interface DC_INT3n : in std_logic; DC_INT1n : in std_logic; DC_INT0n : in std_logic; -- Voltage Control CORE_VCNTL0 : out std_logic; CORE_VCNTL1 : out std_logic; -- WAKE_UP_SW : in std_logic; -- Sample period generator ENABLE : in std_logic; VARCLK : in std_logic; NI_DIG : out std_logic_vector( 7 downto 0 ); USB_XF : in std_logic; EVENT_TRG : out std_logic; CAPTURE_POWER_ON : in std_logic ); end cntlcpld; ----------------------------------------------------------------------------------- -- Include standard librariess ----------------------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; ----------------------------------------------------------------------------------- -- Include fpga specifics here if required. -- act3 is for Actel 54sx devices. We normally use this for the hardwired -- clock definition. ----------------------------------------------------------------------------------- architecture behavior_cntlcpld of cntlcpld is constant CPLD_VERSION : std_logic_vector(3 downto 0) := "0001"; constant PWB_REV : std_logic_vector(3 downto 0) := "0000"; ----------------------------------------------------------------------------------- -- Add local components in here ----------------------------------------------------------------------------------- --component MyComponent --port --( --); --end component; ----------------------------------------------------------------------------------- -- Add signals ----------------------------------------------------------------------------------- -- CPLD Register signals signal REG_CEn : std_logic; signal CpldReg0 : std_logic_vector( 7 downto 0 ); signal CpldReg1 : std_logic_vector( 7 downto 0 ); signal CpldReg4 : std_logic_vector( 7 downto 0 ); signal CpldReg6 : std_logic_vector( 7 downto 0 ); signal CpldReg7 : std_logic_vector( 7 downto 0 ); signal MuxD : std_logic_vector( 7 downto 0 ); signal ChipEnables : std_logic_vector( 10 downto 0 ); signal CpldRegCs0 : std_logic; signal CpldRegCs1 : std_logic; signal CpldRegCs2 : std_logic; signal CpldRegCs3 : std_logic; signal CpldRegCs4 : std_logic; signal CpldRegCs5 : std_logic; signal CpldRegCs6 : std_logic; signal CpldRegCs7 : std_logic; signal CpldRegCs8 : std_logic; signal CpldRegCs9 : std_logic; signal POWER_UP : std_logic; signal SystemResetn : std_logic; signal NiHiz : std_logic; signal NiEnable : std_logic; signal NiForceOn : std_logic; -- SAMPLE RATE GENERATOR -- High time is 255-47 = 208 -- Low time is 47 -- This supports a 24MHz FXCLK and 3MHz VARCLK which is a 8:1 ratio. We -- then need 6-VARCLK of high and low clock to get good rising and falling -- edge detection between two clock domains and a capture pulse. -- -- VARCLKS per sample period with 208 FXCLK -- 24:3 = 26 0x0_0001_1010 -- 24:6 = 52 0x0_0011_0100 -- 24:12 = 104 0x0_0110_1000 -- 24:24 = 208 0x0_1101_0000 -- 24:48 = 416 0x1_1010_0000 -- constant SAMPLE_HIGH : std_logic_vector( 7 downto 0 ) := "00101111"; constant SAMPLE_LOW : std_logic_vector( 7 downto 0 ) := "11111111"; signal SampleCounter : std_logic_vector( 7 downto 0 ); signal SampleEnable : std_logic; signal VarCounter : std_logic_vector( 8 downto 0 ); signal VarEnable : std_logic; signal VarSyncEnable : std_logic_vector( 3 downto 0 ); signal VarCapture : std_logic; signal VarLatch : std_logic_vector( 4 downto 0 ); signal FXCLK : std_logic; ----------------------------------------------------------------------------------- -- The implementation ----------------------------------------------------------------------------------- begin ----------------------------------------------------------------------------------- -- Actel specific definition for the hardwired clock "hclk" ----------------------------------------------------------------------------------- -- u1: HCLKBUF port map( PAD => iMasterClockIn, Y => oMasterClockIn ); ----------------------------------------------------------------------------------- -- Map the other components ----------------------------------------------------------------------------------- --u2: my_component port map ( ComponentSignalName => SignalConnection, ... ); ----------------------------------------------------------------------------------- -- Now define the logic ----------------------------------------------------------------------------------- -- Generate a reset from the three sources. May need to deglitch based on -- external implementation. -- -- Generate a CPLD clockout from clock input. This is a place holder just in -- case we need it later. -- SystemResetn <= '0' when ( PONRSn = '0' or PUSHBRS = '1' or USB_DSP_RS = '0' ) else '1'; DSP_RSn <= '0' when SystemResetn = '0' else '1'; DSP_RS_LEDn <= '0' when SystemResetn = '0' else '1'; FLASH_RSn <= '0' when SystemResetn = '0' else '1'; USB_PORSTn <= '0' when PONRSn = '0' else '1'; FLASH_CEn <= '0' when ( ( DSP_CS1n = '0' and DSP_ADDR20 = '0' ) or ( DSP_CS1n = '0' and DSP_ADDR20 = '1' and DSP_ADDR19 = '0') or ( DSP_CS1n = '0' and DSP_ADDR20 = '1' and DSP_ADDR18 = '0') or ( DSP_CS1n = '0' and DSP_ADDR20 = '1' and DSP_ADDR17 = '0') ) else '1'; REG_CEn <= '0' when ( DSP_CS1n = '0' and DSP_ADDR20 = '1' and DSP_ADDR19 = '1' and DSP_ADDR18 = '1' and DSP_ADDR17 = '1' ) else '1'; --######################################################################### -- Generic register addresss decode and register chip select generation. -- VHDL compiler will reduce any unused logic so we can be verbose. -- process( DSP_ADDR ) begin case DSP_ADDR( 4 downto 1) is when "0000" => ChipEnables <= "00000000001"; when "0001" => ChipEnables <= "00000000010"; when "0010" => ChipEnables <= "00000000100"; when "0011" => ChipEnables <= "00000001000"; when "0100" => ChipEnables <= "00000010000"; when "0101" => ChipEnables <= "00000100000"; when "0110" => ChipEnables <= "00001000000"; when "0111" => ChipEnables <= "00010000000"; when "1000" => ChipEnables <= "00100000000"; when "1001" => ChipEnables <= "01000000000"; when "1010" => ChipEnables <= "10000000000"; when others => ChipEnables <= "00000000000"; end case; end process; CpldRegCs0 <= '1' when ChipEnables(0) = '1' and REG_CEn = '0' else '0'; CpldRegCs1 <= '1' when ChipEnables(1) = '1' and REG_CEn = '0' else '0'; CpldRegCs2 <= '1' when ChipEnables(2) = '1' and REG_CEn = '0' else '0'; CpldRegCs3 <= '1' when ChipEnables(3) = '1' and REG_CEn = '0' else '0'; CpldRegCs4 <= '1' when ChipEnables(4) = '1' and REG_CEn = '0' else '0'; CpldRegCs5 <= '1' when ChipEnables(5) = '1' and REG_CEn = '0' else '0'; CpldRegCs6 <= '1' when ChipEnables(6) = '1' and REG_CEn = '0' else '0'; CpldRegCs7 <= '1' when ChipEnables(7) = '1' and REG_CEn = '0' else '0'; CpldRegCs8 <= '1' when ChipEnables(8) = '1' and REG_CEn = '0' else '0'; CpldRegCs9 <= '1' when ChipEnables(9) = '1' and REG_CEn = '0' else '0'; -- ######################################################################### -- Generate logic for each CPLD register and assign it's write, read, and -- pin values if necessary. -- -- All CPLD register writes occur on the rising edge DSP write strobe. -- -- ======================================================================== -- REG 0: User Register -- Bit 3-0 Led 3-0 -- Bit 7-4 Switch 3-0 process( SystemResetn, DSP_WEn, CpldRegCs0, DSP_DQ ) begin if SystemResetn = '0' then CpldReg0(3 downto 0 ) <= "0000"; elsif DSP_WEn'event and DSP_WEn = '1' then if( CpldRegCs0 = '1' ) then CpldReg0( 3 downto 0 ) <= DSP_DQ( 3 downto 0 ); end if; end if; end process; CpldReg0(7 downto 4 ) <= USER_SW( 3 downto 0 ); USER_LED( 3 downto 0 ) <= not CpldReg0(3 downto 0 ); -- ======================================================================== -- REG 1: DC Register -- Bit 1-0 DC_CNTL 1-0 -- Bit 2 RESERVED -- Bit 3 DC_RESET -- Bit 5-4 DC_STAT 1-0 -- Bit 6 RESERVED -- Bit 7 DC_DETECT -- process( SystemResetn, DSP_WEn, CpldRegCs1, DSP_DQ ) begin if SystemResetn = '0' then CpldReg1( 1 downto 0 ) <= "00"; CpldReg1(3) <= '0'; elsif DSP_WEn'event and DSP_WEn = '1' then if( CpldRegCs1 = '1' ) then CpldReg1( 1 downto 0 ) <= DSP_DQ( 1 downto 0 ); CpldReg1(3) <= DSP_DQ(3); end if; end if; end process; CpldReg1(2) <= '0'; CpldReg1(5 downto 4 ) <= DC_STAT( 1 downto 0 ); CpldReg1(6) <= '0'; CpldReg1(7) <= not DC_DETn; DC_CNTL( 1 downto 0 ) <= CpldReg1( 1 downto 0 ); DC_RESETn <= '0' when CpldReg1(3) = '1' or DC_POR = '0' else '1'; -- ======================================================================== -- REG 4: Version Register -- Bit 2-0 PWB Revision 2-0 -- Bit 3 NU read 0 -- Bit 7-4 CPLD version CpldReg4(7 downto 0 ) <= CPLD_VERSION(3 downto 0 ) & PWB_REV(3 downto 0 ); -- ======================================================================== -- REG 6: Misc. Register -- Bit 0 RESERVED -- Bit 1 RESERVED -- Bit 2 TIMER IN/OUT SELECT -- Bit 3 EVENT_TRIG (ni section) -- Bit 4 CORE VCNTL SELECT -- Bit 5 NiForceOn - test bit -- Bit 6 CORE_VCNTL0 VALUE -- Bit 7 CORE_VCNTL1 VALUE process( SystemResetn, DSP_WEn, CpldRegCs6, DSP_DQ ) begin if SystemResetn = '0' then CpldReg6 <= "00000000"; elsif DSP_WEn'event and DSP_WEn = '1' then if( CpldRegCs6 = '1' ) then CpldReg6 <= DSP_DQ; end if; end if; end process; DSP_TINOUT_0 <= X_TIN0 when CpldReg6(2) = '1' else 'Z'; X_TOUT0 <= DSP_TINOUT_0 when CpldReg6(2) = '0' else 'Z'; CORE_VCNTL0 <= CpldReg6(6) when CpldReg6(4) = '1' else DSP_GP5; CORE_VCNTL1 <= CpldReg6(7) when CpldReg6(4) = '1' else DSP_GP6; NiForceOn <= CpldReg6(5); -- ======================================================================== -- REG 7: Interrupt Register -- Bit 0 RESERVED -- Bit 1 RESERVED -- Bit 2 RESERVED -- Bit 3 RESERVED -- Bit 4 RESERVED -- Bit 5 RESERVED -- Bit 6 RESERVED -- Bit 7 RESERVED process( SystemResetn, DSP_WEn, CpldRegCs7, DSP_DQ ) begin if SystemResetn = '0' then CpldReg7 <= "00000000"; elsif DSP_WEn'event and DSP_WEn = '1' then if( CpldRegCs7 = '1' ) then CpldReg7 <= DSP_DQ; end if; end if; end process; --- POWER_UP <= PON_CORE; DSP_INT0 <= '0' when ( ( CpldReg7(0) = '1' and WAKE_UP_SW = '1' ) OR ( CpldReg7(4) = '1' and POWER_UP = '1' ) OR ( DC_INT0n = '0' ) ) else '1'; DSP_INT1 <= '0' when ( ( CpldReg7(1) = '1' and WAKE_UP_SW = '1' ) OR ( CpldReg7(5) = '1' and POWER_UP = '1' ) OR ( DC_INT1n = '0' ) ) else '1'; DSP_INT3 <= '0' when ( ( CpldReg7(3) = '1' and WAKE_UP_SW = '1' ) OR ( CpldReg7(7) = '1' and POWER_UP = '1' ) OR ( DC_INT3n = '0' ) ) else '1'; -- ======================================================================= -- Mux the read data from all the registers and output for reads -- process( DSP_ADDR,CpldReg0,CpldReg1,CpldReg4,CpldReg6,CpldReg7 ) begin case DSP_ADDR( 4 downto 1) is when "0000" => MuxD <= CpldReg0; when "0001" => MuxD <= CpldReg1; when "0100" => MuxD <= CpldReg4; when "0110" => MuxD <= CpldReg6; when "0111" => MuxD <= CpldReg7; when "1000" => MuxD <= NiForceOn & CAPTURE_POWER_ON & VarEnable & VarLatch(4 downto 0 ); when others => MuxD <= "00000000"; end case; end process; DSP_DQ <= MuxD when DSP_CS1n = '0' and DSP_REn = '0' and DSP_OEn = '0' and DSP_ADDR17 = '1' and DSP_ADDR18 = '1' and DSP_ADDR19 = '1' -- for UART or CPLD Select and DSP_ADDR20 = '1' else "ZZZZZZZZ"; -- ######################################################################### -- Generate the Daughter card buffer control signals -- -- Point the data buffer direction to the DC if not reading. -- Only enable the DC buffer if reading and daughter card is installed -- Only enable control ouput signals if daughter card is installed -- DC_DBUF_OEn <= '0' when ( DC_DETn = '0' and DSP_CS2n = '0') or ( DC_DETn = '0' and DSP_CS3n = '0') else '1'; DC_CNTL_OEn <= '0' when DC_DETn = '0' else '1'; DC_DBUF_DIR <= DSP_REn; -- ======================================================================== -- SAMPLE RATE GENERATOR -- -- Simple counter to generate the sample period FXCLK <= CLKIN; NiEnable <= '1' when ( ( ENABLE = '1' and SystemResetn = '1') or ( NiForceOn = '1' ) ) else '0'; process( NiEnable, FXCLK ) begin if( NiEnable = '0' ) then SampleCounter <= (others => '0'); elsif FXCLK'event and FXCLK = '1' then SampleCounter <= SampleCounter + 1; end if; end process; -- Create an enable signal based on the FXCLK process( NiEnable, FXCLK, SampleCounter ) begin if( NiEnable = '0' ) then SampleEnable <= '0'; elsif FXCLK'event and FXCLK = '1' then if ( SampleCounter = SAMPLE_HIGH) then SampleEnable <= '1'; elsif( SampleCounter = SAMPLE_LOW ) then SampleEnable <= '0'; end if; end if; end process; -- Move the SampleEnable from FXCLK domain to the VARCLK domain process( NiEnable, VARCLK, SampleEnable) begin if( NiEnable = '0' ) then VarSyncEnable <= ( others => '0' ); elsif VARCLK'event and VARCLK = '1' then VarSyncEnable(0) <= SampleEnable; VarSyncEnable(1) <= VarSyncEnable(0); VarSyncEnable(2) <= VarSyncEnable(1); VarSyncEnable(3) <= VarSyncEnable(2); end if; end process; -- Enables the var counter VarEnable <= VarSyncEnable(1); -- Capture on falling edge of VarEnable. This requires that -- SampleEnable is at least 6 VARCLKs high to detect both -- falling and rising edges through the sync logic; VarCapture <= '1' when VarSyncEnable = "1000" else '0'; -- Count VARCLKs -- VarEnable -- ___|-----------------|________________|--------------- -- VarCapture -- _______________________|--|___________________________ -- VarCounter -- 000X count X----00000000 -- VarLatch -- --------------------------XCount--------------------- -- Capture and Clear ^ -- process( NiEnable, VARCLK, VarEnable ) begin if( NiEnable = '0' ) then VarCounter <= (others => '0'); elsif VARCLK'event and VARCLK = '1' then -- Clear on VarCapture else count when enabled if( VarCapture = '1' ) then VarCounter <= ( others => '0'); elsif ( VarEnable = '1' ) then VarCounter <= VarCounter + 1; end if; end if; end process; -- Capture at end of sample period process( NiEnable, VARCLK, VarCapture, VarCounter ) begin if( NiEnable = '0' ) then VarLatch <= (others => '0'); elsif VARCLK'event and VARCLK = '1' then if( VarCapture = '1' ) then VarLatch(4 downto 0 ) <= VarCounter( 8 downto 4); end if; end if; end process; -- ====================================== -- CODE 4-0 : NI_DIG 4-0 -- SAMPLE_PERIOD : NI_DIG 5 -- TRIGGER : NI_DIG 6 -- ENABLE : NI_DIG 7 NiHiz <= '1' when ( ( CAPTURE_POWER_ON = '1' and SystemResetn = '1' and ENABLE = '1' ) or ( NiForceOn = '0' )) else '0'; NI_DIG(4 downto 0) <= VarLatch when NiHiz = '0' else "ZZZZZ"; NI_DIG(5) <= VarEnable when NiHiz = '0' else 'Z'; NI_DIG(6) <= VarCapture when NiHiz = '0' else 'Z'; NI_DIG(7) <= USB_XF when NiHiz = '0' else 'Z'; EVENT_TRG <= CpldReg6(3) when NiHiz = '0' else 'Z'; end behavior_cntlcpld;