Fix bugs in AC97 output for Atlys board.
* Fix bugs in AC97 synchronization. * Fix bugs in AC97 reset. * Reduce audio volume to -12 dB. * Set correct voltage for reset button on Atlys board.
This commit is contained in:
parent
8bd2d389ef
commit
398dca67b6
|
@ -1,5 +1,8 @@
|
|||
--
|
||||
-- Simple core for AC97 audio output.
|
||||
--
|
||||
-- Sets output volume to -12 dB,
|
||||
-- then plays stereo PCM data at 48 kHz sample rate.
|
||||
-- Only tested with LM4550 on Digilent Atlys board.
|
||||
--
|
||||
|
||||
|
@ -13,8 +16,8 @@ entity ac97out is
|
|||
-- AC97 bit clock.
|
||||
bitclk: in std_logic;
|
||||
|
||||
-- Synchronous reset, active high.
|
||||
rst: in std_logic;
|
||||
-- Asynchronous reset, active low.
|
||||
resetn: in std_logic;
|
||||
|
||||
-- Input samples for left and right channel.
|
||||
data_left: in signed(19 downto 0);
|
||||
|
@ -25,6 +28,7 @@ entity ac97out is
|
|||
data_ready: out std_logic;
|
||||
|
||||
-- AC97 interface signals.
|
||||
ac97_sdi: in std_logic;
|
||||
ac97_sdo: out std_logic;
|
||||
ac97_sync: out std_logic );
|
||||
|
||||
|
@ -37,12 +41,12 @@ architecture rtl of ac97out is
|
|||
constant init_table: init_table_type := (
|
||||
-- write 0x0000 to register 0x00: soft reset
|
||||
x"000000",
|
||||
-- write 0x0000 to register 0x02: set master volume to maximum
|
||||
x"020000",
|
||||
-- write 0x0000 to register 0x04: set headphone volume to maximum
|
||||
x"040000",
|
||||
-- write 0x0000 to register 0x06: set mono_out volume to maximum
|
||||
x"060000",
|
||||
-- write 0x0000 to register 0x02: set master volume to -12 dB
|
||||
x"020808",
|
||||
-- write 0x0000 to register 0x04: set headphone volume to -12 dB
|
||||
x"040808",
|
||||
-- write 0x0000 to register 0x06: set mono_out volume to -12 dB
|
||||
x"060008",
|
||||
-- write 0x0808 to register 0x18: set PCM out volume to 0 dB
|
||||
x"180808",
|
||||
-- dummy read from register 0x00
|
||||
|
@ -51,15 +55,21 @@ architecture rtl of ac97out is
|
|||
x"800000" );
|
||||
|
||||
-- Output registers.
|
||||
signal r_ready: std_logic;
|
||||
signal r_sdo: std_logic;
|
||||
signal r_sync: std_logic;
|
||||
|
||||
-- Reset synchronization.
|
||||
signal r_rstsync: std_logic_vector(7 downto 0);
|
||||
|
||||
-- Bit counter.
|
||||
signal r_bitcnt: unsigned(7 downto 0);
|
||||
signal r_lastbit: std_logic;
|
||||
signal r_firstbit: std_logic;
|
||||
signal r_endsync: std_logic;
|
||||
|
||||
-- Initialization state machine.
|
||||
signal r_initwait: unsigned(5 downto 0);
|
||||
signal r_initbusy: std_logic;
|
||||
signal r_initdone: std_logic;
|
||||
signal r_initstep: unsigned(2 downto 0);
|
||||
signal r_initword: std_logic_vector(23 downto 0);
|
||||
|
@ -72,20 +82,46 @@ architecture rtl of ac97out is
|
|||
-- Frame data shift register (tag + slots 1 .. 4)
|
||||
signal r_sdoshift: std_logic_vector(95 downto 0);
|
||||
|
||||
-- AC97 bit input register
|
||||
signal r_sdi: std_logic;
|
||||
|
||||
begin
|
||||
|
||||
-- Drive outputs.
|
||||
data_ready <= not r_datavalid;
|
||||
data_ready <= r_ready;
|
||||
ac97_sdo <= r_sdo;
|
||||
ac97_sync <= r_sync;
|
||||
|
||||
-- Synchronous process.
|
||||
-- Sample AC97_SDI on falling edge of BITCLK.
|
||||
process (bitclk) is
|
||||
begin
|
||||
if rising_edge(bitclk) then
|
||||
if falling_edge(bitclk) then
|
||||
r_sdi <= ac97_sdi;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Drive SYNC high on first bit of frame.
|
||||
r_sync <= r_firstbit;
|
||||
-- Synchronous process.
|
||||
process (bitclk, resetn) is
|
||||
begin
|
||||
if resetn = '0' then
|
||||
|
||||
-- Asynchronous reset.
|
||||
r_rstsync <= (others => '0');
|
||||
r_ready <= '0';
|
||||
|
||||
-- Outputs to codec must be low during reset.
|
||||
r_sdo <= '0';
|
||||
r_sync <= '0';
|
||||
|
||||
elsif rising_edge(bitclk) then
|
||||
|
||||
-- Drive SYNC high for 16 cycles at start of frame.
|
||||
if r_lastbit = '1' then
|
||||
r_sync <= '1';
|
||||
elsif r_endsync = '1' then
|
||||
r_sync <= '0';
|
||||
end if;
|
||||
|
||||
-- Push next data bit to output.
|
||||
r_sdo <= r_sdoshift(r_sdoshift'high);
|
||||
|
@ -108,8 +144,8 @@ begin
|
|||
r_sdoshift(95) <= '1';
|
||||
|
||||
-- Set slots 1 and 2 valid if we are initializing.
|
||||
r_sdoshift(94) <= not r_initdone;
|
||||
r_sdoshift(93) <= not r_initdone;
|
||||
r_sdoshift(94) <= r_initbusy;
|
||||
r_sdoshift(93) <= r_initbusy;
|
||||
|
||||
-- Set slots 3 and 4 valid if we have valid data.
|
||||
r_sdoshift(92) <= r_datavalid;
|
||||
|
@ -122,7 +158,7 @@ begin
|
|||
-- bit 19 = read (1) or write (0)
|
||||
-- bit 18:12 = address
|
||||
r_sdoshift(79 downto 72) <= r_initword(23 downto 16);
|
||||
r_sdoshift(71 downto 0) <= (others => '0');
|
||||
r_sdoshift(71 downto 60) <= (others => '0');
|
||||
|
||||
-- Slot 2: Register write data.
|
||||
-- bit 19:4 = data
|
||||
|
@ -130,42 +166,65 @@ begin
|
|||
r_sdoshift(43 downto 40) <= (others => '0');
|
||||
|
||||
-- Update init pointer.
|
||||
if r_initbusy = '1' then
|
||||
r_initstep <= r_initstep + 1;
|
||||
end if;
|
||||
if r_initstep = 7 then
|
||||
r_initbusy <= '0';
|
||||
r_initdone <= '1';
|
||||
end if;
|
||||
|
||||
-- Update init delay counter (wait for 1.3 ms after reset).
|
||||
r_initwait <= r_initwait - 1;
|
||||
if r_initwait = 0 then
|
||||
r_initstep <= (others => '0');
|
||||
r_initbusy <= not r_initdone;
|
||||
end if;
|
||||
|
||||
-- Slots 3 and 4: left and right sample value.
|
||||
r_sdoshift(39 downto 20) <= r_dataleft;
|
||||
r_sdoshift(19 downto 0) <= r_dataright;
|
||||
|
||||
-- Consume sample values.
|
||||
r_datavalid <= '0';
|
||||
r_ready <= '1';
|
||||
|
||||
end if;
|
||||
|
||||
-- Update bit counter.
|
||||
r_bitcnt <= r_bitcnt - 1;
|
||||
r_firstbit <= r_lastbit;
|
||||
if r_bitcnt = 1 then
|
||||
r_lastbit <= '1';
|
||||
else
|
||||
r_lastbit <= '0';
|
||||
end if;
|
||||
if r_bitcnt = 241 then
|
||||
r_endsync <= '1';
|
||||
else
|
||||
r_endsync <= '0';
|
||||
end if;
|
||||
|
||||
-- Capture input data.
|
||||
if r_datavalid = '0' and data_valid = '1' then
|
||||
if r_ready = '1' and data_valid = '1' then
|
||||
r_ready <= '0';
|
||||
r_datavalid <= '1';
|
||||
r_dataleft <= std_logic_vector(data_left);
|
||||
r_dataright <= std_logic_vector(data_right);
|
||||
end if;
|
||||
|
||||
-- Release synchronous reset.
|
||||
r_rstsync <= "1" & r_rstsync(7 downto 1);
|
||||
|
||||
-- Synchronous reset.
|
||||
if rst = '1' then
|
||||
if r_rstsync(0) = '0' then
|
||||
r_ready <= '0';
|
||||
r_sdo <= '0';
|
||||
r_sync <= '0';
|
||||
r_initbusy <= '0';
|
||||
r_initdone <= '0';
|
||||
r_initwait <= (others => '1');
|
||||
r_initstep <= (others => '0');
|
||||
r_bitcnt <= (others => '0');
|
||||
r_firstbit <= '0';
|
||||
r_datavalid <= '0';
|
||||
end if;
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ NET "clk" TNM_NET = "clk" ;
|
|||
TIMESPEC "TS_clk" = PERIOD "clk" 10 ns HIGH 50% ;
|
||||
|
||||
# Reset button
|
||||
NET "resetn" LOC = "T15" | IOSTANDARD = LVCMOS18 ;
|
||||
NET "resetn" LOC = "T15" | IOSTANDARD = LVCMOS33 ;
|
||||
|
||||
# LEDs
|
||||
NET "led<0>" LOC = "U18" | IOSTANDARD = LVCMOS33 | SLEW = QUIETIO ;
|
||||
|
@ -21,7 +21,7 @@ NET "led<7>" LOC = "N12" | IOSTANDARD = LVCMOS33 | SLEW = QUIETIO ;
|
|||
|
||||
# USB serial port J17
|
||||
NET "uartrx" LOC = "A16" | IOSTANDARD = LVCMOS33 ;
|
||||
NET "uarttx" LOC = "B16" | IOSTANDARD = LVCMOS33 ;
|
||||
NET "uarttx" LOC = "B16" | IOSTANDARD = LVCMOS33 | SLEW = SLOW ;
|
||||
|
||||
# Audio
|
||||
NET "ac97_bitclk" LOC = "L13" | IOSTANDARD = LVCMOS33 ;
|
||||
|
|
|
@ -103,7 +103,7 @@
|
|||
<status xil_pn:value="SuccessfullyRun"/>
|
||||
<status xil_pn:value="ReadyToRun"/>
|
||||
</transform>
|
||||
<transform xil_pn:end_ts="1461346689" xil_pn:in_ck="2072574044500593778" xil_pn:name="TRANEXT_xstsynthesize_spartan6" xil_pn:prop_ck="8668749107623387584" xil_pn:start_ts="1461346674">
|
||||
<transform xil_pn:end_ts="1461403854" xil_pn:in_ck="2072574044500593778" xil_pn:name="TRANEXT_xstsynthesize_spartan6" xil_pn:prop_ck="8668749107623387584" xil_pn:start_ts="1461403839">
|
||||
<status xil_pn:value="SuccessfullyRun"/>
|
||||
<status xil_pn:value="WarningsGenerated"/>
|
||||
<status xil_pn:value="ReadyToRun"/>
|
||||
|
@ -121,11 +121,11 @@
|
|||
<outfile xil_pn:name="webtalk_pn.xml"/>
|
||||
<outfile xil_pn:name="xst"/>
|
||||
</transform>
|
||||
<transform xil_pn:end_ts="1461346689" xil_pn:in_ck="141509727442713" xil_pn:name="TRAN_compileBCD2" xil_pn:prop_ck="7075349975164966765" xil_pn:start_ts="1461346689">
|
||||
<transform xil_pn:end_ts="1461400807" xil_pn:in_ck="141509727442713" xil_pn:name="TRAN_compileBCD2" xil_pn:prop_ck="7075349975164966765" xil_pn:start_ts="1461400807">
|
||||
<status xil_pn:value="SuccessfullyRun"/>
|
||||
<status xil_pn:value="ReadyToRun"/>
|
||||
</transform>
|
||||
<transform xil_pn:end_ts="1461346696" xil_pn:in_ck="-1047380743607608193" xil_pn:name="TRANEXT_ngdbuild_FPGA" xil_pn:prop_ck="392032481918333458" xil_pn:start_ts="1461346689">
|
||||
<transform xil_pn:end_ts="1461403860" xil_pn:in_ck="-1047380743607608193" xil_pn:name="TRANEXT_ngdbuild_FPGA" xil_pn:prop_ck="392032481918333458" xil_pn:start_ts="1461403854">
|
||||
<status xil_pn:value="SuccessfullyRun"/>
|
||||
<status xil_pn:value="ReadyToRun"/>
|
||||
<outfile xil_pn:name="_ngo"/>
|
||||
|
@ -134,10 +134,12 @@
|
|||
<outfile xil_pn:name="top_test_sincos.ngd"/>
|
||||
<outfile xil_pn:name="top_test_sincos_ngdbuild.xrpt"/>
|
||||
</transform>
|
||||
<transform xil_pn:end_ts="1461346726" xil_pn:in_ck="-1047380743607608192" xil_pn:name="TRANEXT_map_spartan6" xil_pn:prop_ck="4245753365082497697" xil_pn:start_ts="1461346696">
|
||||
<transform xil_pn:end_ts="1461403888" xil_pn:in_ck="-1047380743607608192" xil_pn:name="TRANEXT_map_spartan6" xil_pn:prop_ck="4245753365082497697" xil_pn:start_ts="1461403860">
|
||||
<status xil_pn:value="SuccessfullyRun"/>
|
||||
<status xil_pn:value="WarningsGenerated"/>
|
||||
<status xil_pn:value="ReadyToRun"/>
|
||||
<status xil_pn:value="OutOfDateForOutputs"/>
|
||||
<status xil_pn:value="OutputChanged"/>
|
||||
<outfile xil_pn:name="_xmsgs/map.xmsgs"/>
|
||||
<outfile xil_pn:name="top_test_sincos.pcf"/>
|
||||
<outfile xil_pn:name="top_test_sincos_map.map"/>
|
||||
|
@ -148,7 +150,7 @@
|
|||
<outfile xil_pn:name="top_test_sincos_summary.xml"/>
|
||||
<outfile xil_pn:name="top_test_sincos_usage.xml"/>
|
||||
</transform>
|
||||
<transform xil_pn:end_ts="1461346754" xil_pn:in_ck="693365441136831385" xil_pn:name="TRANEXT_par_spartan6" xil_pn:prop_ck="-3829590541433901613" xil_pn:start_ts="1461346726">
|
||||
<transform xil_pn:end_ts="1461403915" xil_pn:in_ck="693365441136831385" xil_pn:name="TRANEXT_par_spartan6" xil_pn:prop_ck="-3829590541433901613" xil_pn:start_ts="1461403888">
|
||||
<status xil_pn:value="SuccessfullyRun"/>
|
||||
<status xil_pn:value="WarningsGenerated"/>
|
||||
<status xil_pn:value="ReadyToRun"/>
|
||||
|
@ -163,7 +165,7 @@
|
|||
<outfile xil_pn:name="top_test_sincos_pad.txt"/>
|
||||
<outfile xil_pn:name="top_test_sincos_par.xrpt"/>
|
||||
</transform>
|
||||
<transform xil_pn:end_ts="1461346939" xil_pn:in_ck="4016941542054796675" xil_pn:name="TRANEXT_bitFile_spartan6" xil_pn:prop_ck="97434230493978268" xil_pn:start_ts="1461346923">
|
||||
<transform xil_pn:end_ts="1461403932" xil_pn:in_ck="4016941542054796675" xil_pn:name="TRANEXT_bitFile_spartan6" xil_pn:prop_ck="97434230493978268" xil_pn:start_ts="1461403915">
|
||||
<status xil_pn:value="SuccessfullyRun"/>
|
||||
<status xil_pn:value="WarningsGenerated"/>
|
||||
<status xil_pn:value="ReadyToRun"/>
|
||||
|
@ -176,7 +178,7 @@
|
|||
<outfile xil_pn:name="webtalk.log"/>
|
||||
<outfile xil_pn:name="webtalk_pn.xml"/>
|
||||
</transform>
|
||||
<transform xil_pn:end_ts="1461346754" xil_pn:in_ck="-1047380743607608324" xil_pn:name="TRAN_postRouteTrce" xil_pn:prop_ck="445577401284416185" xil_pn:start_ts="1461346746">
|
||||
<transform xil_pn:end_ts="1461403915" xil_pn:in_ck="-1047380743607608324" xil_pn:name="TRAN_postRouteTrce" xil_pn:prop_ck="445577401284416185" xil_pn:start_ts="1461403907">
|
||||
<status xil_pn:value="SuccessfullyRun"/>
|
||||
<status xil_pn:value="WarningsGenerated"/>
|
||||
<status xil_pn:value="ReadyToRun"/>
|
||||
|
|
|
@ -246,6 +246,7 @@
|
|||
<property xil_pn:name="Preferred Language" xil_pn:value="VHDL" xil_pn:valueState="non-default"/>
|
||||
<property xil_pn:name="Produce Verbose Report" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Project Description" xil_pn:value="" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Project Generator" xil_pn:value="ProjNav" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Property Specification in Project File" xil_pn:value="Store all values" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="RAM Extraction" xil_pn:value="true" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="RAM Style" xil_pn:value="Auto" xil_pn:valueState="default"/>
|
||||
|
|
|
@ -73,7 +73,6 @@ architecture rtl of top_test_sincos is
|
|||
|
||||
signal r_ac97_rstcnt: unsigned(7 downto 0);
|
||||
signal r_ac97_rst: std_logic;
|
||||
signal r_ac97_rstsync: std_logic_vector(7 downto 0);
|
||||
signal r_ac97_phase: unsigned(19 downto 0);
|
||||
signal s_ac97_sine: signed(17 downto 0);
|
||||
signal s_ac97_dataleft: signed(19 downto 0);
|
||||
|
@ -109,14 +108,16 @@ begin
|
|||
u2: entity work.ac97out
|
||||
port map (
|
||||
bitclk => ac97_bitclk,
|
||||
rst => r_ac97_rstsync(0),
|
||||
resetn => r_ac97_rst,
|
||||
data_left => s_ac97_dataleft,
|
||||
data_right => s_ac97_dataright,
|
||||
data_valid => '1',
|
||||
data_ready => s_ac97_ready,
|
||||
ac97_sdi => ac97_sdi,
|
||||
ac97_sdo => ac97_sdo,
|
||||
ac97_sync => ac97_sync );
|
||||
|
||||
-- Pad 18-bit signed samples to 20-bit.
|
||||
s_ac97_dataleft <= s_ac97_sine & "00";
|
||||
s_ac97_dataright <= s_ac97_sine & "00";
|
||||
|
||||
|
@ -157,13 +158,9 @@ begin
|
|||
end process;
|
||||
|
||||
-- Synchronous process in AC97 bitclock domain.
|
||||
process (ac97_bitclk, r_ac97_rst) is
|
||||
process (ac97_bitclk) is
|
||||
begin
|
||||
if r_ac97_rst = '0' then
|
||||
r_ac97_rstsync <= (others => '1');
|
||||
r_ac97_phase <= (others => '0');
|
||||
elsif rising_edge(ac97_bitclk) then
|
||||
r_ac97_rstsync <= "0" & r_ac97_rstsync(7 downto 1);
|
||||
if rising_edge(ac97_bitclk) then
|
||||
if s_ac97_ready = '1' then
|
||||
r_ac97_phase <= r_ac97_phase + tone_freq;
|
||||
end if;
|
||||
|
|
Loading…
Reference in New Issue