python 开发板 i2s_[Craftor原创] I2S总线接口设计(Verilog)

本文有Craftor原创,转载请保留出处。

I2S是数字音频的接口,这里不用多说,请读者自己查阅相关资料。

本文中要设计的是FPGA与数字音频芯片的I2S接口时序。简单点说,就是通过FPGA向音频芯片写数据,通过的是I2S总线,因为这个总线比较麻烦,我在这里做成接口模块,其它模块直接拿来用就可以了。

提示,I2S总线的接口信号如下:

1、LRCLK:左右声道控制,高电平时,SDATA上为左声道数据,低电平时,SDATA上为右声道数据。(也有相反的情况,请参考不同的音频芯片的手册)

2、BCLK:跟SDATA上数据对应的时钟,上升沿采数据,也可能在下降沿采数据,请注意对应音频芯片手册上的说明。

3、SDATA:串行数据,一个BCLK对应一个。

时序图如下,WS就是LRCLK,BCLK就是SCK。

20111106111629848.png

一、设计思路,数据流向,如下:

201111061116329089.png

二、分析

左声道和右声道的数据,分别设计成两个FIFO即可。重点在于如何将两路数据拼装到一起,再转换成串行的数据。

三、设计

1、LRCLK和BCLK的产生

提示,如果数字音频的数据是16位的,那么BCLK就是LRCLK的16倍。即在一个LRCLK中,有32个BCLK,16个左声道数据,16个右声道数据。同样,如果数据是12位的,那么BCLK就是LRCLK的24倍。

verilog代码如下:

// LRCLK & BCLK Generate

reg [7:0] lrclk_cnt = 0;

reg [2:0] bclk_cnt = 0;

always@(posedge clk) begin

lrclk_cnt <= lrclk_cnt + 1;

if (lrclk_cnt == 127) audio_lrclk <= 1'b1;

if (lrclk_cnt == 255) audio_lrclk <= 1'b0;

end

always@(posedge clk) begin

bclk_cnt <= bclk_cnt + 1;

if (bclk_cnt == 3) audio_bclk <= 1'b1;

if (bclk_cnt == 7) audio_bclk <= 1'b0;

end

说明,如果音频数据的采样率是48KHz,那么,一般情况下,clk应该是采样率的256、384或者512倍。比较常见的是256倍,那么,这里的clk=44.8KHz*256=12.288MHz。

之所以用这种计数器的方式产生LRCLK和BCLK,是为下面的装入数据做准备的。

2、SDATA数据的载入

// DAC Data Assembling

reg [15:0] lbuf = 16'd0;

reg [15:0] rbuf = 16'd0;

always@(negedge clk) begin

case(lrclk_cnt)

// Left

0: audio_sdata <= lbuf[15];

8: audio_sdata <= lbuf[14];

16: audio_sdata <= lbuf[13];

24: audio_sdata <= lbuf[12];

32: audio_sdata <= lbuf[11];

40: audio_sdata <= lbuf[10];

48: audio_sdata <= lbuf[9];

56: audio_sdata <= lbuf[8];

64: audio_sdata <= lbuf[7];

72: audio_sdata <= lbuf[6];

80: audio_sdata <= lbuf[5];

88: audio_sdata <= lbuf[4];

96: audio_sdata <= lbuf[3];

104: audio_sdata <= lbuf[2];

112: audio_sdata <= lbuf[1];

120: audio_sdata <= lbuf[0];

// Right

128: audio_sdata <= rbuf[15];

136: audio_sdata <= rbuf[14];

144: audio_sdata <= rbuf[13];

152: audio_sdata <= rbuf[12];

160: audio_sdata <= rbuf[11];

168: audio_sdata <= rbuf[10];

176: audio_sdata <= rbuf[9];

184: audio_sdata <= rbuf[8];

192: audio_sdata <= rbuf[7];

200: audio_sdata <= rbuf[6];

208: audio_sdata <= rbuf[5];

216: audio_sdata <= rbuf[4];

224: audio_sdata <= rbuf[3];

232: audio_sdata <= rbuf[2];

240: audio_sdata <= rbuf[1];

248: audio_sdata <= rbuf[0];

endcase

end

说明,至于在计数器的哪个值上将数据赋值,以上的代码都是经过仿真和实测的,读者可以自己仿真观察一下就知道了。

3、FIFO数据的读取

第2节代码中可以看到,sdata的数据是从lbuf和rbuf中取的,那么下面的模块就是如何将数据从FIFO中取出,并放到lbur和rbuf中了。

// Fetch Audio Data From FIFO

assign lfifo_rd_clk = clk;

assign rfifo_rd_clk = clk;

always@(negedge clk) begin

case(lrclk_cnt)

125:

begin

if(!rfifo_empty) rfifo_rd_en <= 1;

end

126:

begin

rfifo_rd_en <= 0;

rbuf <= rfifo_dout;

end

253:

begin

if(!lfifo_empty) lfifo_rd_en <= 1;

end

254:

begin

lfifo_rd_en <= 0;

lbuf <= lfifo_dout;

end

endcase

end

说明,上面取数据对应的计数器值也是经过仿真和实测的,没有问题,读者可以自己仿真观察下。

最后,上面的代码都是经过作者实测的。

测试情况:

1、找一个mp3或者其它音频文件,48KHz的采样率以上,如果采样率不是48KHz的,通过Adobe Audition(原Cool Edit)软件调整采样率(升采样率会出现杂音,你懂的)。

2、用Matlab打开,可以看到在计算机上的音频文件的数据是经过归一化的。将他们转化成16位的二进制数(unsigned int类型的也一样),然后另存为二进制文件。

3、通过USB接口(见EZ-USB与FPGA的通信接口设计),自己编写的软件,将这个二进制文件发送下去。FPGA端连续不断的将数据输出即可听到声音。(软件通过USB发送数据下去的时候,最好将文件切成1K的段发下去,因为FPGA的FIFO缓冲区没那么大,USB发送数据的延时等待也要设置成200ms以上,不然数据流会断掉)

文中完整的代码:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/507718.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux内核态获取ip地址,Linux内核支持动态获取IP地址

配置选项&#xff1a;NFS: Network File SystemPNP: Plug-and-PlayCONFIG_ROOT_NFS若想要Linux box通过NFS依赖网络上的其他计算机来mount其整个根文件系统(假定该机器没有硬盘)&#xff0c;则配置为Y。此时&#xff0c;可能还需要将"内核IP自动配置"设置为Y, 以便本…

深度学习(1)--引言

表示学习(representation learning) 使用机器学习来发掘表示本身&#xff0c;而不仅仅把表示映射到输出。 表示学习算法的典型例子为自编码器(autoencoder)。自编码器由一个编码器(encoder)函数和一个解码器(decoder) 函数组合而成。 编码器&#xff1a;将输入数据转换为一种…

pycharm配置python环境变量_求教大家 pycharm 中,环境变量 path 的问题!

问题的发现 在 pycharm 里把一个编译好的二进制文件放到/usr/local/bin/&#xff0c;然后在程序里调用。 cmmd "xxx ..." os.system(cmmd) 报这样的错&#xff0c;但是/usr/local/bin/已经在环境变量 path 里。 sh: xxx: command not found 最简单的解决办法就是把上…

linux nohup 运行,linux – 如何获取使用nohup运行的程序列表

当我开始使用$ nohup风暴dev-zookeper时&#xff0c;方法1&#xff1a;prayagupdprayagupd:/home/vmfest# jobs -l[1] 11129 Running nohup ~/bin/storm/bin/storm dev-zookeeper &方法2&#xff1a;使用ps命令。$ ps xwPID TTY STAT TIME COMMAND1031 tty1 Ss 0:00 /sbin/…

深度学习(2)--常见概率分布(1)

许多简单的概率分布在机器学习的众多领域中都非常有用&#xff0c;这个内容将分为两个部分来说明&#xff0c;第一个部分介绍伯努利分布、二项式分布、多项式分布及范畴分布&#xff0c;第二个部分介绍高斯分布、指数分布、Laplace分布、Dirac分布、经验分布及混合分布。 伯努…

gdb 调试_GDB调试指南-源码查看

前言我们在调试过程中难免要对照源码进行查看&#xff0c;如果已经开始了调试&#xff0c;而查看源码或者编辑源码却要另外打开一个窗口&#xff0c;那未免显得太麻烦。文本将会介绍如何在GDB调试模式下查看源码或对源码进行编辑。 准备工作为了说明后面的内容&#xff0c;我们…

suse linux 11如何分区,新手发帖,关于SUSE11挂载磁盘阵列并分区的问题

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼以下是盘阵给的代码&#xff1a;解压缩软件[rootRedHat5 ~]# tar xvzf Open-iscsi-2.0.865.tar.gz在/root下生成目录Open-iscsi-2.0.86&#xff0c;进入该目录进行编译和安装[rootRedHat5 ~]# cd Open-iscsi-2.0.86[rootRedHat5 Op…

深度学习(2)--常见概率分布(2)

上一部分介绍了伯努利分布、二项式分布、多项式分布以及范畴分布&#xff0c;这里将继续介绍高斯分布、指数分布、Laplace分布、Dirac分布、经验分布及混合分布。 高斯分布 高斯分布又称为正态分布&#xff0c;其图形为钟形曲线(bell-shaped curve)&#xff0c;特点是中间高、…

update 千万数据_mysql学习(四)数据库

创建数据库create database 数据库名; 创建数据库的时候&#xff0c;我们应该记住以下几点&#xff1a; 1 不能与其他数据库名重复 2 名称可以由任意字母&#xff0c;阿拉伯数字&#xff0c;下划线&#xff0c;美元符&#xff0c;但是必须以字母开头 3 名称最长为64个字符&…

linux gpio按键驱动程序,Linux GPIO Key 驱动的加载

gpio-keys是基于input子系统实现的一个通用的GPIO按键驱动,基于platform来实现,位于drivers/input/keyboard/gpio_keys.c,这个文件是硬件无关的,而硬件有关的需要我们自己来注册.进入这个gpio_keys.c这个函数,第一步就是初始化.static int __init gpio_keys_init(void){return …

深度学习(3)--常用激活函数的有用性质

1 sigmoid函数 sigmoid函数是一个在生物学中常见的S型函数&#xff0c;也称为S型生长曲线。 sigmoid函数由下列公式定义: σ(x)11e−x(1)\sigma(x) \frac{1}{1 e^{-x}} \tag1σ(x)1e−x1​(1) sigmoid函数的级数表示&#xff1a; σ(x)1214x−148x31480x5−1780640x73114515…

kvm虚拟机不通网关_linux ssh 虚拟机下CentOS7开启SSH连接

一. 没开启&#xff0c;连接会报错二. 开启后&#xff0c;连接成功在虚拟机(Vmware Workstation)下&#xff0c;安装了CentOS7&#xff0c;现在想通过SSH工具连接虚拟机中的CentOS71、 首先&#xff0c;要确保CentOS7安装了 openssh-server&#xff0c;在终端中输入 yum list i…

linux netstat服务,linux netstat查看服务和端口状态

netstat可以查看linux系统中正在使用的服务和端口情况常见参数-a (all)显示所有选项&#xff0c;默认不显示LISTEN相关-t (tcp)仅显示tcp相关选项-u (udp)仅显示udp相关选项-n 拒绝显示别名&#xff0c;能显示数字的全部转化成数字。-l 仅列出有在 Listen (监听) 的服务状态-p …

memcpy函数实现_等比例缩放c++ opencv 实现

背景&#xff1a;在目标检测算法中&#xff0c; 输入图片等比例resize时mAP比直接resize会高几个点。实现&#xff1a;使用c 和opencv实现(之所以没用python&#xff0c;是因为用于生产环境)先贴代码&#xff1a;#include <math.h> #include <opencv2/core/core.hpp&g…

linux的bh文件停止运行,linux 系统 rcu_bh self-detected stall 问题处理

问题说明近期几台 linux 机器都报了以下 kernel 提示:Apr 24 21:02:09 cztest kernel: INFO: rcu_bh self-detected stall on CPU { 0} (t0 jiffies)Apr 24 21:02:09 cztest kernel: Pid: 0, comm: swapper/0 Not tainted 3.4.95.R620.CentOS6.5-x86_64.OpenBeta.KVM #1Apr 24 …

睡眠音频分割及识别问题(十一)--基于Android的YAMNet音频识别(总结)

WAV文件格式介绍 WAV文件遵守资源交换文件格式之规则&#xff0c;在文件的前44(或46)字节放置标头(header)&#xff0c;使播放器或编辑器能够简单掌握文件的基本信息&#xff0c;其内容以区块(chunk)为最小单位&#xff0c;每一区块长度为4字节&#xff0c;而区块之上则由子区…

安卓第一行代码第3版pdf_SPECFEM2D用户手册——第3章 网格生成——3.1 如何使用SPECFEM2D...

参考资料manual_SPECFEM2D.pdf数值实现Julia 1.4.2/MATLAB 2019a备用系统Ubuntu 64地球物理局 地震波动力学实验室 谱元组 译# 声明 # 欢迎批评指正&#xff0c;禁止转载&#xff01;目 录石中居士&#xff1a;地震波场正演模拟中的谱元法&#xff1a;基本原理与程序实现——目…

黑白棋游戏水平(2)--pytorch剪裁

系统需求 Linux系统&#xff0c;并已安装git、gcc、g、cmake⼯具 下载源码 从github克隆Pytorch仓库 git clone --recursive https://github.com/pytorch/pytorch如果已经克隆过&#xff0c;则使⽤以下命令更新 git submodule sync git submodule update --init --recurs…

linux htb 源代码,LINUX TC:HTB相关源码

LINUX TC:HTB相关源码 收藏HTB(hierarchy token buffer)是linux tc(traffic control)模块中的排队队列的一种。它的配置比CBQ要简单.同时实现功能也很强大。下面&#xff0c;就来看看&#xff0c;HTB在linux中的源码。1、 Qdisc_ops的注册先从module_init函数看起(…

二维码图像去噪文献调研(1)--Real Image Denoising with Feature Attention

简介 &#xff08;1&#xff09; 论文&#xff08;包括期刊和发表时间&#xff09;&#xff1a; Real Image Denoising with Feature Attention&#xff08;ICCV 2019&#xff09; &#xff08;2&#xff09; 论文链接&#xff1a; https://arxiv.org/pdf/1904.07396.pdf &…