zhangmangui 发表于 2020-1-9 22:20

FPGA与DSP EMIF接口译码程序

------------------------------------------------------------------------------------
-- $Archive::                                                                      $
-- $Revision::                                                                     $
-- $Date::                                                                         $
-- $Author::                                                                     $
--
--
--
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
-- Start the real code                  
------------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
--
--
--   

entity c5509aevm 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_WEn      : in    std_logic;                         -- DSP Write strobe
    DSP_REn      : in    std_logic;                         -- DSP Read strobe
    DSP_OEn      : in    std_logic;                         -- DSP Output enable

    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 );

                -- NI Interface

                DIGIO1      :outstd_logic;
                DIGIO0      :outstd_logic;

    -- LCD Interface

                oLCD_A0       : outstd_logic;
                oLCD_SI       : outstd_logic;
                oLCD_SCK      : outstd_logic;
                oLCD_RESET   : outstd_logic;


               -- 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      : inout    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;

    --McBSP Multiplexer Control

    MCBSP_ONBD_SEL2   : out   std_logic;
                MCBSP_EXP_SEL2    : out   std_logic;
    MCBSP_ONBD_SEL0   : out   std_logic;

    --
               
    WAKE_UP_SW      : in std_logic);

               ----
   --                CPLD_Option       : in    std_logic );
end c5509aevm;

-----------------------------------------------------------------------------------
-- Include standard librariess
-----------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
-- use work.std_arith.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;

-----------------------------------------------------------------------------------
-- Include fpga specifics here if required.
-- act3is for Actel 54sx devices.We normally use this for the hardwired
-- clock definition.
-----------------------------------------------------------------------------------
-- library act3;
-- use act3.components.all;

architecture behavior_c5509aevm of c5509aevm is      

constant CPLD_VERSION         : std_logic_vector(3 downto 0):= "0000";
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    MclkDiv         : std_logic_vector( 1 downto 0 );
signal    LcdClkEn         : std_logic;

signal    LcdA0            : std_logic;
signal    LcdD               : std_logic_vector( 7 downto 0 );
signal    LcdRequest         : std_logic;
signal    LcdStart         : std_logic;
signal    LCD_BUSY         : std_logic;

signal    LcdMuxD            : std_logic;
signal    LcdShiftCnt      : std_logic_vector( 2 downto 0 );
signal    LcdSckOn         : std_logic;


signal    REG_CEn         : std_logic;
signal    CpldReg0      : std_logic_vector( 7 downto 0 );
signal    CpldReg1      : std_logic_vector( 7 downto 0 );
signal    CpldReg2      : std_logic_vector( 7 downto 0 );
signal    CpldReg3      : std_logic_vector( 7 downto 0 );
signal    CpldReg4      : std_logic_vector( 7 downto 0 );
signal    CpldReg5      : std_logic_vector( 7 downto 0 );
signal    CpldReg6      : std_logic_vector( 7 downto 0 );
signal    CpldReg7      : std_logic_vector( 7 downto 0 );
signal    CpldReg8      : std_logic_vector( 7 downto 0 );
signal    CpldReg9      : std_logic_vector( 7 downto 0 );
signal    CpldReg10       : 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    CpldRegCs10   : std_logic;

signal    POWER_UP      :std_logic;

signal    SystemResetn    : std_logic;
signal    CpldClkOut      : 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';
        CpldRegCs10 <= '1' when ChipEnables(10) = '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   McBSP0 aic23 enable
        -- Bit 1   MCBsp2 expansion
        -- Bit 2   RESERVED
        -- Bit 3   RESERVED
        -- Bit 4   RESERVED
        -- Bit 5   RESERVED
        -- Bit 6   RESERVED
        -- Bit 7   mcbsp0 select
        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;

       

        MCBSP_ONBD_SEL0 <=NOT CpldReg6(0);
          
MCBSP_ONBD_SEL2 <=CpldReg6(1);

MCBSP_EXP_SEL2<= NOT CpldReg6(1);

        DSP_TINOUT_0 <=X_TIN0 when CpldReg6(2) = '1'
                                  else 'Z';

        X_TOUT0 <= DSP_TINOUT_0 when CpldReg6(2) = '1'
                                  else 'Z';               


CORE_VCNTL0 <=CpldReg6(6) when CpldReg6(4) = '1'
                                  else DSP_GP5;       

CORE_VCNTL1 <= CpldReg6(7) when CpldReg6(4) = '1'
                           else DSP_GP6;       

        DIGIO1<= CpldReg6(7) when CpldReg6(4) = '1'
                           else DSP_GP6;          

        DIGIO0 <=CpldReg6(6) when CpldReg6(4) = '0'
                                  else DSP_GP5;             


        -- ========================================================================
        -- 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' andWAKE_UP_SW = '1') OR
                        (CpldReg7(4) = '1' andPOWER_UP= '1' ) OR
                                                                                                (DC_INT0n   = '0'))
                               else '1';       

DSP_INT1 <= '0' when ((CpldReg7(1) = '1' andWAKE_UP_SW = '1') OR
                        (CpldReg7(5) = '1' andPOWER_UP   = '1') OR
                                                                                          (DC_INT1n   = '0'))
                               else '1';       

DSP_INT3 <= '0' when ((CpldReg7(3) = '1' andWAKE_UP_SW = '1') OR
                        (CpldReg7(7) = '1' andPOWER_UP   = '1') OR
                                                                                          (DC_INT3n   = '0'))
                               else '1';       



-- #################################################################
        -- LCD
        --
       
        -- Create a divide by 4 clock with a LcdClkEn.
        -- DivClk    LcdClkEn
        --   00      0
        --   01      0
        --   10      1
        --   11      0
        -- All states operate on Mclk when LcdClkEn = '1'.
        -- A 1-100
        -- A 1-101
        --
process( SystemResetn, CLKIN )
        begin
          if SystemResetn = '0' then
                  MclkDiv<= (others => '0' );
                        LcdClkEn <= '0';
                elsif CLKIN'event and CLKIN = '1' then

                  MclkDiv <= MclkDiv + 1;
                       
                        if( MclkDiv = "10" ) then
                          LcdClkEn <= '1';
                        else
                          LcdClkEn <= '0';
                  end if;
                end if;
        end process;

        -- Latch the data and address on the rising edge of DSP_WEnn
        process( DSP_WEn, SystemResetn,CpldRegCs8,CpldRegCs9,DSP_DQ)
        begin
          if SystemResetn = '0' then
                  LcdD <= ( others => '0' );
                                LcdA0 <= '0';
                elsif DSP_WEn'event and DSP_WEn = '1' then
                  if (   CpldRegCs8 = '1'
                             orCpldRegCs9 = '1' ) then
                                       LcdD <= DSP_DQ;
                                       LcdA0 <=DSP_ADDR(1);
                        end if;
                end if;
        end process;

        -- Generate a LCD Start edge.We clear the edge once we have
        -- detected it with LcdStart.
        process( DSP_WEn, SystemResetn, CpldRegCs8, CpldRegCs9, LcdStart )
        begin
          if SystemResetn = '0' or LcdStart = '1' then
      LcdRequest <= '0';
                elsif DSP_WEn'event and DSP_WEn = '1' then
                  if (   CpldRegCs8 = '1'
                             orCpldRegCs9 = '1' ) then
                                       LcdRequest <= '1';
                        end if;
                end if;
        end process;

        -- Generate the LCD start request.
        -- If we have a spare flip-flop we should sync before
        -- using it.
        --
process( SystemResetn, CLKIN, LcdRequest, LcdClkEn )
        begin
          if SystemResetn = '0' then
      LcdStart <= '0';
                elsif CLKIN'event and CLKIN = '1' then
      if( LcdClkEn = '1' ) then
                                  LcdStart <= LcdRequest;
                                end if;
                end if;
        end process;

        -- Load the shift count with 0 on start and count up to 7
        -- The LcdSckOn signal is ON for Load/Count and OFF otherwise.
        --
process( SystemResetn, CLKIN, LcdStart, LcdClkEn )
        begin
          if SystemResetn = '0' then
      LcdShiftCnt <= (others => '1');
                                LcdSckOn    <= '0';
                elsif CLKIN'event and CLKIN = '1' then
      if( LcdClkEn = '1' ) then
                                  LcdSckOn <= '0';   -- Default
            if LcdStart = '1' then
                                             LcdShiftCnt <= "000";
                                                       LcdSckOn    <= '1';
                                                else
                                                  if LcdShiftCnt /= "111" then
                                                           LcdShiftCnt <= LcdShiftCnt + "001";
                                                               LcdSckOn<= '1';
                                                        end if;
                                          end if;
                                end if;
                end if;
        end process;

        -- Mux out the data
        process( LcdShiftCnt, LcdD )
        begin
           case LcdShiftCnt( 2 downto 0 ) is
                  when "111"   => LcdMuxD <= LcdD(0);
                  when "110"   => LcdMuxD <= LcdD(1);
                  when "101"   => LcdMuxD <= LcdD(2);
                  when "100"   => LcdMuxD <= LcdD(3);
                  when "011"   => LcdMuxD <= LcdD(4);
                  when "010"   => LcdMuxD <= LcdD(5);
                  when "001"   => LcdMuxD <= LcdD(6);
                  when others=> LcdMuxD <= LcdD(7);
    end case;
        end process;

        oLCD_SI   <= LcdMuxD;
        oLCD_SCK<= MclkDiv(1) when LcdSckOn = '1' else '1';
        oLCD_A0   <= LcdA0;
        LCD_BUSY <= '0' when (    LcdRequest= '1'
                               or LcdStart    = '1'
                                                                                               or LcdSckOn    = '1' ) else '1';



        -- ========================================================================
        -- REG 10: xxxx. Register
        -- Bit 0   RESERVED
        -- Bit 1   RESERVED
        -- Bit 2   RESERVED
        -- Bit 3   RESERVED
        -- Bit 4   RESERVED
        -- Bit 5   RESERVED
        -- Bit 6   KEYBOARD_RESET
        -- Bit 7   REad LCD_BUSY
        process( SystemResetn, DSP_WEn, CpldRegCs10, DSP_DQ )
begin
                if SystemResetn = '0' then   
                  CpldReg10 <= "00000000";
                elsif DSP_WEn'event and DSP_WEn = '1' then   
                  if( CpldRegCs10 = '1' ) then
                  CpldReg10 <= DSP_DQ;
                  end if;
                end if;
        end process;

        -- Controls CORE Voltage
       
       
        oLCD_RESET <='0' when SystemResetn = '0' or CpldReg10(6)='1' else '1';







        -- =======================================================================
        -- Mux the read data from all the registers and output for reads
        --
process( DSP_ADDR,LCD_BUSY,CpldReg0,CpldReg1,CpldReg4,CpldReg6,CpldReg7,CpldReg10 )
        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 "1010"=> MuxD<= LCD_BUSY & CpldReg10(6 downto 0 );
                  when others => MuxD<= "00000000";
    end case;
        end process;          
          
        DSP_DQ <= MuxDwhen    DSP_CS1n   = '0'
                         andDSP_REn   = '0'
                         andDSP_OEn   = '0'
                                                                       andDSP_ADDR17 = '1'
                                                                           andDSP_ADDR18 = '1'
                                                                               andDSP_ADDR19 = '1'      -- for UART or CPLD Select
                                                                               andDSP_ADDR20 = '1'
                         else "ZZZZZZZZ";

-- ONBD_BUF_DIR <=NOT DSP_REn;
---
---        ONBD_BUF_OEn <= '0' when (( DSP_CS3n = '0' and CpldReg10(3)='1') or DSP_CS2n = '0'or DSP_CS1n = '0')
---                                                                                                  else '1';

                         

        -- #########################################################################
-- 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;



end behavior_c5509aevm;


页: [1]
查看完整版本: FPGA与DSP EMIF接口译码程序