---------------------------------------------------------------------------------- -- Company: Digilent inc -- Engineer: Kovacs Laszlo - Attila -- -- Create Date: 19:32:30 03/29/2007 -- Design Name: -- Module Name: PModSF - Behavioral -- Project Name: -- Target Device: Nexys3, PModSF -- Tool versions: Xilinx ISE design suite 13.2 -- Description: -- -- Dependencies: -- -- Revision: -- Revision 0.01 - File Created -- Additional Comments: -- ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; ---- Uncomment the following library declaration if instantiating ---- any Xilinx primitives in this code. --library UNISIM; --use UNISIM.VComponents.all; entity PModSF is Port ( Clk : in std_logic; Address : in std_logic_vector(7 downto 0); DataIn : in std_logic_vector(7 downto 0); DataOut : out std_logic_vector(7 downto 0); Read : in std_logic; Write : in std_logic; DataRdy : out std_logic; P1 : out std_logic; P2 : out std_logic; P3 : in std_logic; P4 : out std_logic); end PModSF; architecture Behavioral of PModSF is type stateType is (stIdle, stCode, stAddr0, stAddr1, stAddr2, stData, stDone); signal state : stateType := stIdle; signal nextState : stateType; constant CMD_ADDR0 : std_logic_vector(7 downto 0) := x"00"; constant CMD_ADDR1 : std_logic_vector(7 downto 0) := x"01"; constant CMD_ADDR2 : std_logic_vector(7 downto 0) := x"02"; constant CMD_COMMAND : std_logic_vector(7 downto 0) := x"03"; constant CMD_DATA : std_logic_vector(7 downto 0) := x"04"; constant CMD_ERASE : std_logic_vector(7 downto 0) := x"05"; constant FLASH_READ : std_logic_vector(7 downto 0) := x"03"; constant FLASH_PROGRAM : std_logic_vector(7 downto 0) := x"02"; constant FLASH_ERASE : std_logic_vector(7 downto 0) := x"D8"; signal fAddress : std_logic_vector(23 downto 0) := x"000000"; signal data : std_logic_vector(7 downto 0) := x"00"; signal cnt : std_logic_vector(3 downto 0) := "1000"; signal serialize, SEL, SDI, SDO, SCK : std_logic; signal reqRead, reqWrite : std_logic := '0'; begin -- flash spi pin mapping P1 <= SEL; P2 <= SDI; SDO <= P3; P4 <= SCK; SCK <= serialize and not Clk; SDI <= data(7); DataOut <= fAddress(7 downto 0) when Address = CMD_ADDR0 else fAddress(15 downto 8) when Address = CMD_ADDR1 else fAddress(23 downto 16) when Address = CMD_ADDR2 else data; serialize <= '0' when cnt = "1000" else '1'; process(Clk) begin if rising_edge(Clk) then -- set Read Request flag if Read = '1' then reqRead <= '1'; elsif serialize = '0' and state = stDone then reqRead <= '0'; end if; -- set Write Request flag if Write = '1' then reqWrite <= '1'; elsif serialize = '0' and state = stDone then reqWrite <= '0'; end if; -- byte serialization procedure with highest priority if serialize = '1' then data <= data(6 downto 0)&SDO; cnt <= cnt + '1'; else -- initiate serialization procedure reseting the bit counter if state = stCode or state = stAddr0 or state = stAddr1 or state = stAddr2 or state = stData then cnt <= (others => '0'); end if; -- on the end of procedure handshake EPP module if state = stDone then DataRdy <= '1'; else DataRdy <= '0'; end if; -- load the Flash Address register if reqWrite = '1' then if Address = CMD_ADDR0 then fAddress(7 downto 0) <= DataIn; end if; if Address = CMD_ADDR1 then fAddress(15 downto 8) <= DataIn; end if; if Address = CMD_ADDR2 then fAddress(23 downto 16) <= DataIn; end if; end if; -- load the serializer buffer with the proper data case state is when stCode => if Address = CMD_ERASE then data <= FLASH_ERASE; elsif reqRead = '1' then data <= FLASH_READ; elsif reqWrite = '1' then data <= FLASH_PROGRAM; else data <= x"00"; end if; when stAddr0 => data <= fAddress(23 downto 16); when stAddr1 => data <= fAddress(15 downto 8); when stAddr2 => data <= fAddress(7 downto 0); when others => data <= DataIn; end case; -- state machine synchronization procedure if reqWrite = '1' or reqRead = '1' then state <= nextState; end if; -- control the Flash Select signal if state = stIdle or state = stDone then SEL <= '1'; else SEL <= '0'; end if; end if; end if; end process; -- state machine next state decode process(state, Address) begin case state is when stIdle => if Address = CMD_COMMAND then nextState <= stData; elsif Address = CMD_DATA or Address = CMD_ERASE then nextState <= stCode; else nextState <= stDone; end if; when stCode => nextState <= stAddr0; when stAddr0 => nextState <= stAddr1; when stAddr1 => nextState <= stAddr2; when stAddr2 => if Address = CMD_ERASE then nextState <= stDone; else nextState <= stData; end if; when stData => nextState <= stDone; when stDone => nextState <= stIdle; when others => nextState <= stIdle; end case; end process; end Behavioral;