library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity MAXconfig is port ( clock : in std_logic; init_done : in std_logic; nStatus : in std_logic; D : in std_logic_vector(7 downto 0); restart : in std_logic; Conf_Done : in std_logic; Data0 : out std_logic; Dclk : out std_logic; nConfig : buffer std_logic; --To increase the size of the memory, change the size of std_logic_vector for ADDR output and --std_logic_vector signal inc: ADDR : out std_logic_vector(15 downto 0); CEn : out std_logic); -- The polarity of the CEn signal is determined by the type of Flash device end; architecture rtl of MAXconfig is --The following encoding is done in such way that the LSB represents the nConfig signal: constant start :std_logic_vector(2 downto 0) := "000"; constant wait_nCfg_8us :std_logic_vector(2 downto 0) := "100"; constant status :std_logic_vector(2 downto 0) := "001"; constant wait_40us :std_logic_vector(2 downto 0) := "101"; constant config :std_logic_vector(2 downto 0) := "011"; constant init :std_logic_vector(2 downto 0) := "111"; signal pp :std_logic_vector(2 downto 0); signal count :std_logic_vector(2 downto 0); signal data0_int, dclk_int :std_logic; signal inc :std_logic_vector(15 downto 0); signal div :std_logic_vector(2 downto 0); signal waitd :std_logic_vector(11 downto 0); --The width of signal ‘waitd’ is determined by the frequency. For 57 MHz (APEX 20KE devices), --‘waitd’ is 12 bits. For 33 MHz (FLEX 10KE and ACEX devices) ‘waitd’ is 11 bits. To calculate --the width of the ‘waitd’ signal fordifferent frequencies, calculate the following: --(multiply tcf2ck * clock frequency)+ 40 --Then convert this value to binary to obtain the width. --For example, for 33 MHz (FLEX 10KE & ACEX devices), converting 1360 ((40us * 33MHz)+40=1360) --to binary code, the ‘waitd’ is an 11-bit signal. So signal ‘waitd’ will be: --signal waitd :std_logic_vector(10 downto 0); begin --The following process is used to divide the CLOCK: PROCESS (clock,restart) begin if restart = '0' then div <= (others => '0'); else IF (clock'EVENT AND clock = '1') THEN div <= div + 1; end if; end if; END PROCESS; PROCESS (clock,restart) begin if restart = '0' then pp<=start; count <= (others => '0'); inc <= (others => '0'); waitd <= (others => '0'); else if clock'event and clock='1' then --The following test is used to divide the CLOCK. The value compared to must be such that the --condition is true at a maximum rate of 57 MHz (tclk = 17.5 ns min) for APEX 20KE devices --and at a maximum rate of 33 MHz (tclk=30ns min) for FLEX 10KE or ACEX devices. if (div = 7) then case pp is when start => count <= (others => '0'); inc <= (others => '0'); waitd <= (others => '0'); pp <= wait_nCfg_8us; --This state is used in order to verify the tcfg timing (nCONFIG low pulse width). --Tcfg = 8µs => min= 456 clock cycle of a 57 MHz clock (APEX 20KE devices). For different --clocks, multiply 8µs to clock frequency. For example, for 33MHz (FLEX 10KE or ACEX devices) --this value is 8*33=264. This clock is CLOCK divided by the divider -div-. when wait_nCfg_8us => count <= (others => '0'); inc <= (others => '0'); waitd <= waitd + 1; if waitd = 456 then --For 33 MHz FLEX 10KE or ACEX devices this line is: if waitd = 264 then pp <= status; end if; --This state is used to have nCONFIG high. when status => count <= (others => '0'); inc <= (others => '0'); waitd <= (others => '0'); pp <= wait_40us; --This state is used to generate the tcf2ck timing (nCONFIG high to first rising edge on DCLK). --Tcf2ck = 40µs min => 2280 clock cycles of a 57MHz (APEX 20KE) clock. This clock is CLOCK --divide by the divider -div- --Tcf2ck = 40µs min => 1320 clock cycles of a 33MHz (FLEX 10KE/ACEX) clock. This clock is CLOCK --divided by the divider -div-) --For any other clock frequency, multiply tcf2ck * clock frequency. when wait_40us => count <= (others => '0'); inc <= (others => '0'); waitd <= waitd + 1; if waitd = 2280 then --For 33 MHz (FLEX 10KE or ACEX devices), this line is: if waitd = 1320 then pp <= config; end if; --This state is used to increment the memory address. In the same state when --the Conf_Done is high clock cycles are added in order to have the initialization completed. when config => count <= count + 1; if Conf_Done='1' then waitd <= waitd + 1; end if; if count=7 then inc <= inc + 1; end if; if waitd = 2320 then --Modification: Add 40 clock cycles. For APEX 20KE devices, it is 2280+40=2320 --For FLEX 10KE and ACEX devices, it is 1320+40=1360. This line becomes: if waitd= 1360 then pp<= init; end if; when init => count <= (others => '0'); inc <= (others => '0'); waitd <= (others => '0'); if nStatus = '0' then pp <= start; else pp <= init; end if; when others => pp <= start; end case; else pp <= pp; inc <= inc; count <= count; end if; end if; end if; end PROCESS; dclk_int <= div(2) when pp=config else '0'; --The following process is used to serialize the data byte : PROCESS (count,D,pp) begin if pp=config then case count is when "000" => data0_int <= D(0); when "001" => data0_int <= D(1); when "010" => data0_int <= D(2); when "011" => data0_int <= D(3); when "100" => data0_int <= D(4); when "101" => data0_int <= D(5); when "110" => data0_int <= D(6); when "111" => data0_int <= D(7); when others => null; end case; else data0_int <= '0'; end if; end PROCESS; nConfig <= pp(0); CEn <= not nconfig; Dclk <= '0' when pp(1)='0' else dclk_int; Data0 <= '0' when pp(1)='0' else data0_int; ADDR <= inc; end;