Kampi Posted May 12, 2016 Share Posted May 12, 2016 Hello, I receive my I2C Audio PMOD (http://store.digilentinc.com/pmodi2s-stereo-audio-output/) today and I want to use it with my ZYBO. My I2S transmitter look like this: library ieee; use ieee.std_logic_1164.all; entity I2S_Transmitter is generic ( DATA_WIDTH : integer := 32 ); port ( Clock : in STD_LOGIC; MCLK : out STD_LOGIC; Data_In : in STD_LOGIC_VECTOR(DATA_WIDTH - 1 downto 0); LRCLK : Out STD_LOGIC; DOUT : out STD_LOGIC; Reset : in STD_LOGIC; Empty : out STD_LOGIC ); end entity; architecture I2S_Transmitter_Arch of I2S_Transmitter is signal InputBuffer : std_logic_vector(DATA_WIDTH - 1 downto 0) := (others => '0'); signal Empty_Signal : std_logic := '1'; signal DOUT_D1 : std_logic := '0'; signal WS : std_logic := '0'; signal Counter : integer := 0; begin LRCLK_Logic: process (Clock) begin if(falling_edge(Clock)) then if(Reset = '1') then Counter <= 0; WS <= '1'; else Counter <= Counter + 1; if(Counter > (DATA_WIDTH / 2 - 1)) then WS <= '1'; else WS <= '0'; end if; if(Counter = (DATA_WIDTH - 1)) then Counter <= 0; end if; end if; end if; end process; Load_and_shift_out_Data: process(Clock) begin if(falling_edge(Clock)) then if(Reset = '1') then InputBuffer <= (others => '0'); Empty_Signal <= '1'; else if(Empty_Signal = '1') then InputBuffer <= Data_In; Empty_Signal <= '0'; else InputBuffer <= InputBuffer((DATA_WIDTH - 2) downto 0) & '0'; DOUT_D1 <= InputBuffer(DATA_WIDTH - 1); end if; if(Counter = (DATA_WIDTH - 1)) then Empty_Signal <= '1'; end if; end if; end if; end process; MCLK <= Clock; LRCLK <= WS; DOUT <= DOUT_D1; Empty <= Empty_Signal; end architecture I2S_Transmitter_Arch; With this Testbench: library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity I2S_Transmitter_TB is -- Port ( ); end I2S_Transmitter_TB; architecture I2S_Transmitter_TB_Arch of I2S_Transmitter_TB is signal MCLK : std_logic; signal WS : std_logic := '0'; signal SCK : std_logic := '1'; signal DOUT : std_logic; signal Empty : std_logic := '0'; signal Reset : std_logic := '0'; signal Data_In : std_logic_vector(31 downto 0) := (others => '0'); -- 8,192 MHz Clock constant clk_period: Time := 122 ns; constant ws_period: Time := 16 * clk_period; begin DUT: entity work.i2s_transmitter port map ( LRCLK => WS, MCLK => MCLK, Data_In => Data_In, Clock => SCK, DOUT => DOUT, Empty => Empty, Reset => Reset ); CLOCK: process begin wait for clk_period / 2; SCK <= not SCK; end process; STIMULUS: process begin Data_In <= x"507B507B"; Reset <= '1'; wait for 10 us; Reset <= '0'; wait for 10 us; Data_In <= (others => '0'); wait for 30 ms; Reset <= '1'; wait for 5 ms; end process; end I2S_Transmitter_TB_Arch; I use Port JC on my ZYBO and this is my XDC-File: # Clock set_property PACKAGE_PIN L16 [get_ports Clock_In] set_property IOSTANDARD LVCMOS33 [get_ports Clock_In] set_property PACKAGE_PIN V15 [get_ports MCLK] set_property IOSTANDARD LVCMOS33 [get_ports MCLK] set_property PACKAGE_PIN W15 [get_ports LRCLK] set_property IOSTANDARD LVCMOS33 [get_ports LRCLK] set_property PACKAGE_PIN T10 [get_ports DOUT] set_property IOSTANDARD LVCMOS33 [get_ports DOUT] set_property IOSTANDARD LVCMOS33 [get_ports DEM] set_property PACKAGE_PIN T11 [get_ports DEM] The clock frequency for MCLK is 8,192MHz, generated with a MMCM. I´ve connected this speaker (http://store.digilentinc.com/speaker/) to the PMOD, but I doesn´t hear any sound. Why? Thank you for help! Link to comment Share on other sites More sharing options...
0 hamster Posted May 13, 2016 Share Posted May 13, 2016 (edited) If I get a chance I'll simulate it this weekend.... but chances are that it is the mismatch of the DAC output impedance and the speaker impedance. The speaker is 4 ohm, and the DAC is for driving 10k ohm loads. Have you got some powered speakers you can test with? For an un-amplifed speaker you might want to use PMOD-AMP3 ( http://store.digilentinc.com/pmodamp3-stereo-power-amplifier ) which is also I2S. As it is a bridged class-D amplifier you can't connect a PMOD-AMP3 to an external power amp but it is ideally suited to to the 4 ohm speaker. Also, sending the clock directly to a pin isn't best practices (but should work for this application). Have a look for "clock forwarding" in http://www.xilinx.com/support/documentation/user_guides/ug471_7Series_SelectIO.pdf at around page 128. Edited May 13, 2016 by hamster Link to comment Share on other sites More sharing options...
0 Kampi Posted May 13, 2016 Author Share Posted May 13, 2016 Hello, thanks for your reply. I don´t have self powered speakers, so I have to buy some :(.... I think I could use . The PMOD-AMP3 looks like a good alternative, but it has I²C for configuration and I want to test I²S alone and without I²C configuration. Otherwise I could choose the audio codec on my ZYBO (which will be the next step after I²S is running). Link to comment Share on other sites More sharing options...
0 okonomiyonda Posted November 16, 2020 Share Posted November 16, 2020 On 5/12/2016 at 11:59 PM, Kampi said: Hello, thanks for your reply. I don´t have self powered speakers, so I have to buy some :(.... I think I could use . The PMOD-AMP3 looks like a good alternative, but it has I²C for configuration and I want to test I²S alone and without I²C configuration. Otherwise I could choose the audio codec on my ZYBO (which will be the next step after I²S is running). Super late on this, but I am posting just in case anyone reads this in the future. AMP3 does indeed have an I2C config mode, but it also has a simple mode that requires no configuration aside from setting some jumpers. You pass it a few clocks, and the I2S serial data, and its off you go. No I2C required Link to comment Share on other sites More sharing options...
0 engi Posted January 15, 2022 Share Posted January 15, 2022 Not sure if it heps, but I wonder, how the PLL setting should cooperate with I2S.(?) Typically you will get or drive the MCLOCK from / to the board with 64xBCLK. This is for instance someting like 12,288 MHz. One chance is to obtain a BLCK and use a PLL to generate an internal multiple of it to get e.g. S/PDIF (BMC) working. If you want to produce I2S or S/PDIF from the PCB and do not have an oscilator with 24.576... you can try to produce a 25MHz Clock with a first PLL and then use a 29/59 to obtain a 12,288 with some 20 ppm error only! One can even use a little load to the OSC to pull it and synch it to an coming clock this way. Link to comment Share on other sites More sharing options...
Question
Kampi
Hello,
I receive my I2C Audio PMOD (http://store.digilentinc.com/pmodi2s-stereo-audio-output/) today and I want to use it with my ZYBO.
My I2S transmitter look like this:
library ieee; use ieee.std_logic_1164.all; entity I2S_Transmitter is generic ( DATA_WIDTH : integer := 32 ); port ( Clock : in STD_LOGIC; MCLK : out STD_LOGIC; Data_In : in STD_LOGIC_VECTOR(DATA_WIDTH - 1 downto 0); LRCLK : Out STD_LOGIC; DOUT : out STD_LOGIC; Reset : in STD_LOGIC; Empty : out STD_LOGIC ); end entity; architecture I2S_Transmitter_Arch of I2S_Transmitter is signal InputBuffer : std_logic_vector(DATA_WIDTH - 1 downto 0) := (others => '0'); signal Empty_Signal : std_logic := '1'; signal DOUT_D1 : std_logic := '0'; signal WS : std_logic := '0'; signal Counter : integer := 0; begin LRCLK_Logic: process (Clock) begin if(falling_edge(Clock)) then if(Reset = '1') then Counter <= 0; WS <= '1'; else Counter <= Counter + 1; if(Counter > (DATA_WIDTH / 2 - 1)) then WS <= '1'; else WS <= '0'; end if; if(Counter = (DATA_WIDTH - 1)) then Counter <= 0; end if; end if; end if; end process; Load_and_shift_out_Data: process(Clock) begin if(falling_edge(Clock)) then if(Reset = '1') then InputBuffer <= (others => '0'); Empty_Signal <= '1'; else if(Empty_Signal = '1') then InputBuffer <= Data_In; Empty_Signal <= '0'; else InputBuffer <= InputBuffer((DATA_WIDTH - 2) downto 0) & '0'; DOUT_D1 <= InputBuffer(DATA_WIDTH - 1); end if; if(Counter = (DATA_WIDTH - 1)) then Empty_Signal <= '1'; end if; end if; end if; end process; MCLK <= Clock; LRCLK <= WS; DOUT <= DOUT_D1; Empty <= Empty_Signal; end architecture I2S_Transmitter_Arch;
With this Testbench:
library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity I2S_Transmitter_TB is -- Port ( ); end I2S_Transmitter_TB; architecture I2S_Transmitter_TB_Arch of I2S_Transmitter_TB is signal MCLK : std_logic; signal WS : std_logic := '0'; signal SCK : std_logic := '1'; signal DOUT : std_logic; signal Empty : std_logic := '0'; signal Reset : std_logic := '0'; signal Data_In : std_logic_vector(31 downto 0) := (others => '0'); -- 8,192 MHz Clock constant clk_period: Time := 122 ns; constant ws_period: Time := 16 * clk_period; begin DUT: entity work.i2s_transmitter port map ( LRCLK => WS, MCLK => MCLK, Data_In => Data_In, Clock => SCK, DOUT => DOUT, Empty => Empty, Reset => Reset ); CLOCK: process begin wait for clk_period / 2; SCK <= not SCK; end process; STIMULUS: process begin Data_In <= x"507B507B"; Reset <= '1'; wait for 10 us; Reset <= '0'; wait for 10 us; Data_In <= (others => '0'); wait for 30 ms; Reset <= '1'; wait for 5 ms; end process; end I2S_Transmitter_TB_Arch;
I use Port JC on my ZYBO and this is my XDC-File:
# Clock set_property PACKAGE_PIN L16 [get_ports Clock_In] set_property IOSTANDARD LVCMOS33 [get_ports Clock_In] set_property PACKAGE_PIN V15 [get_ports MCLK] set_property IOSTANDARD LVCMOS33 [get_ports MCLK] set_property PACKAGE_PIN W15 [get_ports LRCLK] set_property IOSTANDARD LVCMOS33 [get_ports LRCLK] set_property PACKAGE_PIN T10 [get_ports DOUT] set_property IOSTANDARD LVCMOS33 [get_ports DOUT] set_property IOSTANDARD LVCMOS33 [get_ports DEM] set_property PACKAGE_PIN T11 [get_ports DEM]
The clock frequency for MCLK is 8,192MHz, generated with a MMCM. I´ve connected this speaker (http://store.digilentinc.com/speaker/) to the PMOD, but I doesn´t hear any sound. Why?
Thank you for help!
Link to comment
Share on other sites
4 answers to this question
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now