batou 发表于 2012-4-28 13:03:55

VHDl模拟iis通信出现毛刺

 I2S(Inter IC Sound Bus)是飞利浦公司为数字音频设备之间的音频数据传输而制定的一种总线标准,它既规定了硬件接口规范,也规定了数字音频数据的格式。I2S有三个主要的信号:
  (1)串行时钟BCLK,也叫位时钟,即对应于数字音频的每一位数据,BCLK都有一个脉冲。BCLK的频率=2×采样率×采样位数。
  (2)帧时钟LRCLK,用于切换左右声道的数据。LRCLK为“1”表示正在传输的是右声道的数据,为“0”则表示正在传输的是左声道的数据。LRCLK的频率等于采样频率。
  (3)串行数据SDATA,就是用二进制补码表示的音频数据。
  有时为了使系统能够更好的同步,还需要另外传输一个信号MCLK,称为主时钟,也叫系统时钟,是采样频率的256倍或384倍。

下面是我做项目的一个小测试,用VHDl语言模拟音频的dsp通信,输入和输出波形基本一致了,但还是有些毛刺,并且有毛刺的地方输出数据出错,可能因为这点毛刺使得整个系统都不稳定,坛内同仁们有什么解决办法吗
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity dsp_mode is
        PORT(CLK,DIN:IN STD_LOGIC;
                DOUT:OUT STD_LOGIC;
                LRCK,SCLK,MCLK:OUT STD_LOGIC
                );
end;

architecture rtl of dsp_mode is
SIGNAL OUT_DATA_A1: STD_LOGIC_VECTOR(31 DOWNTO 0);
SIGNAL        IN_DATA_A1: STD_LOGIC_VECTOR(31 DOWNTO 0);

COMPONENT dsp IS
        PORT(
                CLK,DIN:IN STD_LOGIC;
                DOUT:OUT STD_LOGIC;
                LRCK,SCLK,MCLK:OUT STD_LOGIC;
                OUT_DATA:buffer STD_LOGIC_VECTOR(31 DOWNTO 0);
                IN_DATA:buffer STD_LOGIC_VECTOR(31 DOWNTO 0)
                );
END COMPONENT;

BEGIN


iis_JJ:dsp PORT MAP
        (
        CLK=>CLK,
        DIN=>DIN,
        DOUT=>DOUT,
        LRCK=>LRCK,
        SCLK=>SCLK,
        MCLK=>MCLK,
        OUT_DATA=>OUT_DATA_A1,
        IN_DATA=>IN_DATA_A1
                );

IN_DATA_A1<=OUT_DATA_A1;

END rtl;




library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity dsp is
        PORT(CLK,DIN:IN STD_LOGIC;
                DOUT:OUT STD_LOGIC;
                LRCK,SCLK,MCLK:OUT STD_LOGIC;
                OUT_DATA:buffer STD_LOGIC_VECTOR(31 DOWNTO 0);
                IN_DATA:buffer STD_LOGIC_VECTOR(31 DOWNTO 0)
                );
end;

architecture rtl of dsp is
SIGNAL CLK_IN:STD_LOGIC;
SIGNAL LRCK_S,SCLK_S:STD_LOGIC:='0';
SIGNAL DSP_RE_DATA:STD_LOGIC_VECTOR(31 DOWNTO 0);
SIGNAL DSP_SE_DATA:STD_LOGIC_VECTOR(31 DOWNTO 0);
SIGNAL NUM_DATA:INTEGER RANGE 0 TO 31:=0;
begin

CLK_IN<=CLK;
MCLK<=CLK_IN;
LRCK<=LRCK_S;
SCLK<=SCLK_S;
DSP_SE_DATA<=IN_DATA;
--DOUT<=DIN;
OUT_DATA<=DSP_RE_DATA;

CLK_SCLK:
        PROCESS(CLK)
        VARIABLE NUM:INTEGER RANGE 0 TO 5;
        BEGIN
                IF CLK'EVENT AND CLK='0'THEN
                        IF NUM=5 THEN
                        SCLK_S<=NOT SCLK_S;
                        NUM:=0;
                        ELSE NUM:=NUM+1;
                        END IF;
                        DOUT<=DSP_SE_DATA(31-NUM_DATA);                       
                END IF;
        END PROCESS CLK_SCLK;


CLK_LRCK:
        PROCESS(SCLK_S)
        VARIABLE NUM:INTEGER RANGE 0 TO 31;
        BEGIN
                IF SCLK_S'EVENT AND SCLK_S='0'THEN
                        IF NUM=31 THEN
                        LRCK_S<='1';
                        NUM:=0;
                        ELSE NUM:=NUM+1;
                        LRCK_S<='0';
                        END IF;
                END IF;
        END PROCESS CLK_LRCK;

RECEIVE_DATA:
        PROCESS(SCLK_S,LRCK_S)
        BEGIN
        IF SCLK_S'EVENT AND SCLK_S='1'THEN
                IF LRCK_S='1'THEN
                NUM_DATA<=0;
                --OUT_DATA<=DSP_RE_DATA;
                ELSE
                        NUM_DATA<=NUM_DATA+1;
                        DSP_RE_DATA(32-NUM_DATA)<=DIN;       
                END IF;       
        END IF;
        END PROCESS RECEIVE_DATA;

end rtl;
下面是我用逻辑分析仪LA2532测得的波形
A0是接收的波形,A1是发送的波形,按理说应该一致,但是A0中有毛刺的地方,A1就输出错误的数据

batou 发表于 2012-4-28 13:09:13

放大后测试了下毛刺的宽度,大约15ns

dragon_hn 发表于 2012-4-29 20:27:23

消除毛刺比较好的方式是用同步时序电路.
整个系统就一个敏感信号:CLK.
其它SCLK,MCLK,LRCK都是根据CLK触发输出.

batou 发表于 2012-4-30 21:24:32

dragon_hn 发表于 2012-4-29 20:27 static/image/common/back.gif
消除毛刺比较好的方式是用同步时序电路.
整个系统就一个敏感信号:CLK.
其它SCLK,MCLK,LRCK都是根据CLK触发 ...

我也想啊,但是每一个LRCK对应16个SCLK,同用CLK,我怕它们对应不上啊

wajlh 发表于 2012-4-30 21:43:04

应该是竞争冒险之类的吧,以前做等精度频率计的时候出现这样的问题,

NJ8888 发表于 2012-4-30 21:51:44

看俩下,没看懂图中波形与你信号的对应关系

batou 发表于 2012-4-30 22:02:23

NJ8888 发表于 2012-4-30 21:51 static/image/common/back.gif
看俩下,没看懂图中波形与你信号的对应关系

你再仔细看看,M0是输入(采集)的波形,M1是输出的波形(就是还原采集的波形),它们没对应上是因为信号传输有延时

NJ8888 发表于 2012-4-30 22:08:00

你是不是说,M0中间部分有个毛刺,导致M1输出错了。如果毛刺比你输入信号宽度小好多,用个RC串到输入端口之前,可能可以消除,15ns很小的

pocker5200 发表于 2012-4-30 22:08:29

说一下你的设计思路呢,看看有没有能改进设计的地方。
毛刺问题很常见的,尤其是组合逻辑电路中。

batou 发表于 2012-5-1 09:21:23

pocker5200 发表于 2012-4-30 22:08 static/image/common/back.gif
说一下你的设计思路呢,看看有没有能改进设计的地方。
毛刺问题很常见的,尤其是组合逻辑电路中。 ...

就是根据他的时序图来的,晶振是16.9344M,用它产生1.441M的BCLK位时钟,然后用这个BCLK产生44.1K的LRCK左右声道采样时钟,最后根据这些时钟接收和发送数据,每一个BCLK接收一位数据,每一个LRCK接收一个声道的数据

wye11083 发表于 2012-5-1 14:50:48

你的输出没有用reg打一拍吧。不管任何时候,端口输出都要用reg打一拍,而且要告诉mapper要把输出reg放到IOB中,否则一则时序难以收敛,二则输出各个寄存器延时不一,产生大量毛刺。输入尽量也用reg输入,置于IOB中,要不然高速信号也难以达到时序要求。对VHDL不是很熟悉,不知道哪些东西会被综合成寄存器,但是我至今都是采用IOB的输入输出reg,一般内核跑100M+,接口~50M。
页: [1]
查看完整版本: VHDl模拟iis通信出现毛刺