📄 cpld_config.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 + -