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

📄 cpld_config.vhd

📁 用Altera CPLD做为控制器从Flash上读取image文件对Altera FPGA编程
💻 VHD
字号:
-----------------------------------------------------------------
-- Design unit: CPLD_Config(rtl) (Entity and Architecture)
--            :
-- File name  : CPLD_Config.vhd
--            :
-- Description: Using FLASH to Config FPGA
--            :
-- Limitations: None
--            : 
-- System     : VHDL'93, STD_LOGIC_1164
--            :
-- Author     : Will Jiang
--		      : 
--		      : 
-- Revision   : Version 1.0 2005.05.22
--              Version 1.1 2005.07.14  Flash_HighA4 only determined in WAIT_CONFIG_L STATE(Line 145)
---------------------------------------------------------------------



library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
package STATEDEFS is
	type STATE_TYPE is (
		RESET,             -- the name means the states
		WAIT_CONFIG_L,
		WAIT_CONFIG_H,
		CONFIGING,
		CONFIG_DONE,
		CONFIG_ERROR
	 );
end STATEDEFS;


library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use work.STATEDEFS.all;
entity CPLD_Config is
generic (
	 	A_width : integer:=24; -- Flash:Am29LV128MH  8/16 bit-width  16MB
	    D_width : integer:=8   -- accept 8 bit-width of DATA Bus
        );
	port
	(   --CLK
		iClk		   	: in std_logic ;  -- 50MHz, pin87
	    oClk_to_FPGA    : out std_logic;  -- 50MHz to FPGA_Global_clk
        --reset
		iReset_n		: in std_logic ;      -- from the power monitor
        oFlash_reset_n      : out std_logic;  -- MAX device used to distribute reset.
        oEnet_reset_n       : out std_logic; 
        oUSB_reset_n   : out std_logic;
        oIO2_reset_n   : out std_logic;
        --button
		iRecover_n  : in std_logic ; -- Recover FPGA using Recovey_hardware image by push-Botton while powerup
		--LED
        oLED_loading: out std_logic; -- LEDs indicate the states
        oLED_error  : out std_logic;
        oLED_user   : out std_logic;
        oLED_recover: out std_logic;

        --PS Mode of FPGA
        oFPGA_CONFIG_n   : out std_logic;    -- from MAX to the Cyclone to start config
        iFPGA_STATUS_n   : in std_logic ;    -- from the FPGA to indicate config's status
        iFPGA_CONF_DONE  : in std_logic ;    -- from the FPGA to indicate finishing Config
		oFPGA_DCLK 	     : out std_logic;    -- config clock from Max to Cyclone in serial, 
        oFPGA_DATA0      : out std_logic;    -- data from Max to Cyclone in serial 
        oFPGA_MSEL       : out std_logic_vector(1 downto 0); -- set the mode(ways,means) of FPGA configrature

        --Flash
 		oFlash_CEn	  	: out std_logic;
		oFlash_OEn	  	: out std_logic;
		oFlash_WEn	  	: out std_logic;
		
		--system
		oFPGA_A         : out std_logic_vector(A_Width-1 downto 0);  --system address bus
		iFPGA_D         : in std_logic_vector(D_Width-1 downto 0)    --system data bus
		--debug
		--oRead_Flash_count_q: out std_logic_vector(2 downto 0);
		--oRequire_data:out std_logic;
		--oBit_count :out std_logic_vector(2 downto 0);
		--oDCLK_cout : out std_logic

	);

  
end CPLD_Config;

architecture a_CPLD_Config of CPLD_Config is
  --constant
  constant START_A: std_logic_vector(A_Width-1 downto 0) := (others => '1'); 
          --where does the Start Address store?  It is in the hightest BYTE.
  --signal
  signal Cur_state,Next_state : STATE_TYPE;								--states
  signal Flash_tristate       : std_logic;								--control Flash
  signal Enable_counter       : std_logic;
  signal Flash_A              : std_logic_vector(A_width-1 downto 0);	--flash address bus
  signal recover_n            : std_logic;                              -- indicate recover button is pressed
  signal Enable_wait_count    : std_logic;								-- to begin a count for delay nCONFIA @40us
  signal Finish_wait          : std_logic;								-- finish signal of  above conut
  signal Flash_low_A          : std_logic_vector(A_width-5 downto 0);	-- low 20 bit-address
  signal q_DCLK_divider       : std_logic_vector(3 downto 0);			-- signal for portmap of DCLK_divider
  signal DCLK_cout            : std_logic;								-- DCLK_cout from DCLK_divider to enable other processes
  signal sigDATA0             : std_logic;								-- just what you see
  signal Bit_count            :std_logic_vector(2 downto 0);			-- Count for shift byte to bit
  signal Flash_HighA4         :std_logic_vector(3 downto 0);			-- high 4- bit-adrees is obtained by flash highest byte
component wait_40us IS          --delay 40us for reconfig
	PORT
	(
		clock		: IN STD_LOGIC ;
		cnt_en		: IN STD_LOGIC ;
		aclr		: IN STD_LOGIC ;
		q		: OUT STD_LOGIC_VECTOR (10 DOWNTO 0);
		cout		: OUT STD_LOGIC 
	);
END component wait_40us;



component DCLK_divider IS      -- divider 50MHz to 3.125MHz (DCLK )
	PORT
	(
		clock		: IN STD_LOGIC ;
		cnt_en		: IN STD_LOGIC ;		
		aclr		: IN STD_LOGIC ;
		cout        : out std_logic;
		q		: OUT STD_LOGIC_VECTOR (3 DOWNTO 0)
	);
END component DCLK_divider;



begin
 -- debug

 --oDCLK_cout <= DCLK_cout;
 --oBit_count<=Bit_count;
 --  oRequire_data <=Require_data;


--inport
recover_n <= '0' when iReset_n= '0' and iRecover_n='0' else
             '1' when iReset_n= '0' and iRecover_n='1';    -- only captured in system reset
Flash_HighA4 <=iFPGA_D(3 downto 0) when recover_n='1' and Cur_state=WAIT_CONFIG_L else -- Just obtain the lowest 4 bit to ognize Flash_A23,A22,A21,A20
               (others =>'1') when recover_n='0' and Cur_state=WAIT_CONFIG_L; -- %20050714% add by Will Jiang
                                                                              -- Flash_HighA4 only determined in WAIT_CONFIG_L STATE
-- oupport

--clock distribute
  oClk_to_FPGA <= iClk;    --output 50MHz clock to FPGA;
                    
--reset distribute
  oFlash_reset_n <= iReset_n;
  oEnet_reset_n  <= iReset_n;
  oUSB_reset_n <= iReset_n;
  oIO2_reset_n <= iReset_n;

--FPGA port
-- DCLK is from 16bit up counter
 oFPGA_DCLK <=q_DCLK_divider(3); 
 oFPGA_DATA0<=sigDATA0; 

 oFPGA_A <= Flash_A when Flash_tristate='0' else
           (others =>'Z');                                               

oFPGA_MSEL <= "01";             -- FPGA Config mode : PS

--Flash outport
oFlash_CEn <='0' when Flash_tristate='0' else        --you konws what's means
             'Z';
oFlash_OEn <='0' when Flash_tristate='0' else        --you konws what's means
             'Z';
oFlash_WEn <='1' when Flash_tristate='0' else        --you konws what's means
             'Z';

----------------------------------------------------------
--port map: Wait_40us
--count for about 40 us for nCONFIG to start FPGA config cycle 

mapWait_40us:Wait_40us
	PORT MAP
	(
		aclr => not iReset_n,
    	clock => iClk,
		cnt_en => Enable_wait_count,
		cout => Finish_wait,
        q => open
	);
----------------------------------------------------------
--port map: DCLK_divider
--count for about 16*20ns=320ns>120ns for Flash read date delay

mapDCLK_divider:DCLK_divider
	PORT MAP
	(
		aclr => not iReset_n,
    	clock => iClk,
		cnt_en => Enable_counter,
        cout  => DCLK_cout,
        q => q_DCLK_divider
	);
           
----------------------------------------------------------
--process:change_states
--for dealing with the states changes by clock and reset

change_states:process(iClk,iReset_n)
begin
	if  (iReset_n = '0') then  --system reset
	    Cur_state <= RESET;
	elsif (iClk'event  and iClk ='1') then    
	    Cur_state <= Next_state; 
	end if;
end process change_states;

----------------------------------------------------------
--process:state_work
-- for dealing with the states changes by clock and reset

state_work:process(Cur_state,Finish_wait,iFPGA_CONF_DONE,iFPGA_STATUS_n,
                   recover_n,iFPGA_D,Flash_low_A,Flash_HighA4)
variable varCONFIG_n : std_logic;
--variable varFlash_HighA4  : std_logic_vector(A_width-1 downto A_width-4); -- high 4 bit-address
begin
--global setting
  oLED_loading <= '0';             -- die LED
  oLED_error   <= '0';
  oLED_user    <= '0';
  oLED_recover <= '0';
  Flash_tristate <= '0';           -- CPLD Accesses the Flash
  Enable_counter <= '0';           -- disable counter: address,clk_div ....
  Enable_wait_count <= '0';        -- disable wait count for nCONFIG in WAIT_CONFIG
  varCONFIG_n    := '1';           -- FPGA dose not always config,isn't it?
  Flash_A        <= START_A;       -- oupput address to address bus
  --varFlash_HighA4:= (others => '1');  --image Hige address

  case Cur_state is
                              -----------------------
                              --reset
                              -----------------------
    when RESET =>             -- the name means the states
      varCONFIG_n    := '0';      -- force FPGA to config
      Next_state     <= WAIT_CONFIG_L;    
      --varFlash_HighA4:= (others => '1');  --image Hige address
                              -----------------------
                              --WAIT_CONFIG_L: wait for another 40 us for nCONFIG<='0'
                              -----------------------
    when WAIT_CONFIG_L =>
      varCONFIG_n    := '0';          -- force FPGA to config
      Enable_wait_count <= '1';       -- begin count for about 40 us for nCONFIG to start FPGA config cycle again
      if (Finish_wait = '1') then     -- count  finished
        Next_state  <= WAIT_CONFIG_H; -- wait state CONF
  --      if(recover_n = '1') then
  --        varFlash_HighA4   := iFPGA_D(3 downto 0); -- Just obtain the lowest 4 bit to ognize Flash_A23,A22,A21,A20
  --      end if;
      else
        Next_state <= WAIT_CONFIG_L;   -- stay until count finished
      end if;
                              -----------------------
                              --WAIT_CONFIG_H : wait for another 40 us for nCONFIG<='1'
                              -----------------------
    when WAIT_CONFIG_H =>
      Enable_wait_count <= '1';       -- begin count for about 40 us for nCONFIG to start FPGA config cycle again
      Flash_A   <= Flash_HighA4 & Flash_low_A; -- outport Flash Address
      if (Finish_wait = '1') then     -- count finished
        Next_state  <= CONFIGING;     -- recover FPGA with recover image
      else
        Next_state <= WAIT_CONFIG_H;  -- stay until count finished
      end if;

                              -----------------------
                              --CONFIGING
                              -----------------------	
	when CONFIGING =>
	    oLED_loading <= '1';        -- light the loading LED
        Enable_counter <= '1';      -- start config here,counter DCLK couter
        Flash_A   <= Flash_HighA4 & Flash_low_A; -- Just obtain the lowest 4 bit to ognize Flash_A23,A22,A21,A20

     
	  if(iFPGA_STATUS_n = '0') then 
	    Next_state <= CONFIG_ERROR;
      elsif (iFPGA_CONF_DONE = '1') then  -- finish config
        Next_state <= CONFIG_DONE;
      else
        Next_state <= CONFIGING;
      end if;
                              -----------------------
                              --CONFIG_DONE
                              -----------------------	
	when CONFIG_DONE =>
        if(recover_n='0') then
          oLED_recover <= '1';        -- light the recover LED
        else
          oLED_user    <= '1';        -- light the user LED
        end if;

         Flash_tristate <= '1';         -- release Flash to other hosts
         Next_state <= CONFIG_DONE;     -- stay around here;    ALWAYS HERE!!!

                              -----------------------
                              --CONFIG_ERROR
                              -----------------------	
	when CONFIG_ERROR =>
         oLED_error <= '1';           -- light the error LED
         Flash_tristate <= '1';       -- release Flash to other hosts

         Next_state <= CONFIG_ERROR;  -- stay around here;


                              -----------------------
                              --others
                              -----------------------	
	when others =>
      null;	
	end case;
-- output some signals	
oFPGA_CONFIG_n <= varCONFIG_n;

end process state_work;

----------------------------------------------------------
--process: Shift_data
-- configing....DATA0 is outporting.....
Shift_data:process(Bit_count,iFPGA_D,Cur_state)
begin
  if(Cur_state=CONFIGING)then                        -- only in the CONFIGING states
    case Bit_count is
    	when "000" => sigDATA0 <= iFPGA_D(0);        --least bit first
	    when "001" => sigDATA0 <= iFPGA_D(1);
		when "010" => sigDATA0 <= iFPGA_D(2);
		when "011" => sigDATA0 <= iFPGA_D(3);
		when "100" => sigDATA0 <= iFPGA_D(4);
		when "101" => sigDATA0 <= iFPGA_D(5);
		when "110" => sigDATA0 <= iFPGA_D(6);
		when "111" => sigDATA0 <= iFPGA_D(7);
		when others => null;
	end case;
  else
    sigDATA0<='0';                                   -- keep sigDATA0 stabl signal '0' or '1'
  end if;

end process Shift_data;
----------------------------------------------------------
--process:Count8
--count byte to bit , count address....

Count8:process(iClk,iReset_n)
begin
	if  (iReset_n = '0') then  --system reset
	   Bit_count <=(others=>'0');
	   Flash_low_A <=(others=>'0');
	elsif (iClk'event  and iClk ='1') then    
	  if(DCLK_cout='1') then        --until 1 Dclk pluse coming
        Bit_count<=Bit_count + 1;   -- Counter for shift byte to bit
      else
        Bit_count<=Bit_count;
      end if;

     if(Bit_count=7 and DCLK_cout='1') then-- until 8 Dclk pluse coming
       Flash_low_A<=Flash_low_A + 1;       -- next data from flash
     else
       Flash_low_A<=Flash_low_A;
     end if;
   end if;
end process Count8;

end architecture a_CPLD_Config;

⌨️ 快捷键说明

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