---------------------------------------------------------------------------------- -- Company: -- Engineer: KOON3876 -- -- Create Date: 12/10/2007 -- Design Name: -- Module Name: FIFO_I2S - Behavioral -- Project Name: -- Target Devices: -- Tool versions: -- Description: -- -- Dependencies: -- -- Revision: -- Revision 0.01 - File Created -- Additional Comments: -- Revision 0.02 - Add CY7C433 FIFO ---------------------------------------------------------------------------------- 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 FIFO_I2S is Port ( RSTN : in STD_Logic; --Reset MCLK : in STD_LOGIC; --11.2896MHz RXFN : in STD_LOGIC; --FT245R Available RDN : out STD_LOGIC; --FT245R Read Signal WCN : out STD_LOGIC; --CY7C433 Write Signal EFN : in STD_LOGIC; --CY7C433 Empty Flag HFN : in STD_LOGIC; --CY7C433 Half Full Flag Q : in STD_LOGIC_VECTOR (7 downto 0); --FIFO Data Out RCN : out STD_LOGIC; --CY7C433 Read Signal LRCK : out STD_LOGIC; --I2S LRCK SCK : out STD_LOGIC; --I2S SCK SD : out STD_LOGIC); --I2S Data end FIFO_I2S; architecture Behavioral of FIFO_I2S is --FT245R and CY7C433 State type STATE_245 is (S0, S1, S2, S3); signal FT245State : STATE_245; type STATE_FIFO is (EMPTY, WAITING, WORKING); signal CY433State : STATE_FIFO; signal FIFO_RDY : STD_LOGIC; --I2S 64 cycle Control signal Count4 : STD_LOGIC_VECTOR (1 downto 0); signal Go_Next : STD_LOGIC; signal I2SState : STD_LOGIC_VECTOR (5 downto 0); --Data Register signal LL : STD_LOGIC_VECTOR (7 downto 0); signal LH : STD_LOGIC_VECTOR (7 downto 0); signal RL : STD_LOGIC_VECTOR (7 downto 0); signal RH : STD_LOGIC_VECTOR (7 downto 0); attribute PWR_MODE : string; attribute PWR_MODE of LL : signal is "low"; attribute PWR_MODE of LH : signal is "low"; attribute PWR_MODE of RL : signal is "low"; attribute PWR_MODE of RH : signal is "low"; begin STATE245_Updates: process(MCLK, RSTN, RXFN, HFN) begin if RSTN = '0' then FT245State <= S0; elsif MCLK' event and MCLK = '1' then case FT245State is --When FT245 is ready (RXFN=0) and CY7C433 available when S0 => if (RXFN = '0') and (HFN = '1') then FT245State <= S1; --start transfer cycle else FT245State <= S0; end if; when S1 => FT245State <= S2; when S2 => FT245State <= S3; when S3 => FT245State <= S0; when others => FT245State <= S0; end case; end if; end process; OUTPUT245_Control : process( FT245State ) begin --initialize output signal RDN <= '1'; WCN <= '1'; case FT245State is when S0 => null; when S1 => RDN <= '0'; WCN <= '0'; --RDN , WCN down when S2 => RDN <= '0'; WCN <= '0'; --Data ready now when S3 => RDN <= '0'; WCN <= '1'; --RDN still 0, WCN up to write when others => null; end case; end process; STATEFIFO_Updates: process(MCLK, RSTN, EFN, HFN) begin if (RSTN = '0') then CY433State <= EMPTY; elsif MCLK' event and MCLK = '1' then if (EFN = '0') then CY433State <= EMPTY; else case CY433State is when EMPTY => CY433State <= WAITING; when WAITING => if (HFN = '0') then --over half filled CY433State <= WORKING; else CY433State <= WAITING; end if; when WORKING => CY433State <= WORKING; when others => CY433State <= EMPTY; end case; end if; end if; end process; OUTPUTFIFOSTATUS: process(CY433State) begin FIFO_RDY <= '0'; case CY433State is when EMPTY => null; when WAITING => null; when WORKING => FIFO_RDY <= '1'; when others => null; end case; end process; COUNTER_4: process(MCLK, RSTN) begin if (RSTN = '0') then Count4 <= "00"; elsif MCLK' event and MCLK = '1' then Count4 <= Count4 + "01"; end if; end process; COUNTER_4_OUT: process(Count4) begin -- I2S State change = 1/4 of MCLK, pulse like 00010001 if (Count4 = "11") then Go_Next <= '1'; else Go_Next <= '0'; end if; -- SCK = also 1/4 of MCLK. like 00110011 SCK <= Count4(1); end process; I2SSTATE_UPDATE: process(MCLK, RSTN, Go_Next) begin if (RSTN = '0') then I2SState <= "000000"; elsif MCLK' event and MCLK = '1' then if (Go_Next = '1') then I2SState <= I2SState + "000001"; end if; end if; end process; FIFO_READ: process(MCLK, RSTN, I2SState, FIFO_RDY) begin if (RSTN = '0') then RCN <= '1'; elsif MCLK' event and MCLK = '1' then if (FIFO_RDY = '1') then case I2SState is when "110100" => RCN <= '0'; when "110110" => RCN <= '0'; when "111000" => RCN <= '0'; when "111010" => RCN <= '0'; when others => RCN <= '1'; end case; end if; end if; end process; DATA_LOAD: process(MCLK, RSTN, I2SState, Go_Next, FIFO_RDY, Q) begin if (RSTN = '0') then LL <= "00000000"; LH <= "00000000"; RL <= "00000000"; RH <= "00000000"; elsif MCLK' event and MCLK = '1' then if (FIFO_RDY = '0') then LL <= "00000000"; LH <= "00000000"; RL <= "00000000"; RH <= "00000000"; else LL <= LL; LH <= LH; RL <= RL; RH <= RH; if (Go_Next = '1') then case I2SState is when "110100" => LL <= Q; when "110110" => LH <= Q; when "111000" => RL <= Q; when "111010" => RH <= Q; when others => null; end case; end if; --Next end if; --FIFO_RDY end if; --RSTN, MCLK end process; I2S_OUT: process(I2SState, LL, LH, RH, RL) begin LRCK <= I2SState(5); SD <= '0'; case I2SState is when "000001" => SD <= LH(7); when "000010" => SD <= LH(6); when "000011" => SD <= LH(5); when "000100" => SD <= LH(4); when "000101" => SD <= LH(3); when "000110" => SD <= LH(2); when "000111" => SD <= LH(1); when "001000" => SD <= LH(0); when "001001" => SD <= LL(7); when "001010" => SD <= LL(6); when "001011" => SD <= LL(5); when "001100" => SD <= LL(4); when "001101" => SD <= LL(3); when "001110" => SD <= LL(2); when "001111" => SD <= LL(1); when "010000" => SD <= LL(0); when "100001" => SD <= RH(7); when "100010" => SD <= RH(6); when "100011" => SD <= RH(5); when "100100" => SD <= RH(4); when "100101" => SD <= RH(3); when "100110" => SD <= RH(2); when "100111" => SD <= RH(1); when "101000" => SD <= RH(0); when "101001" => SD <= RL(7); when "101010" => SD <= RL(6); when "101011" => SD <= RL(5); when "101100" => SD <= RL(4); when "101101" => SD <= RL(3); when "101110" => SD <= RL(2); when "101111" => SD <= RL(1); when "110000" => SD <= RL(0); when others => SD <= '0'; end case; end process; end Behavioral;