FPGA的I2S采集数据处理
0
由于项目需要,需要由FPGA把4路由ADC芯片采集的I2S数据进行合并成1路I2S,最后输出到主控CPU芯片,FPGA在这里起到数据中转的作用。项目的整体结构如下图
(待画)
1.I2S协议
参考文档:I2S bus specification.pdf 见下面博客
参考博客:I2S接口规范时序以及其同DSP的连接
I2S音频总线学习中的一、二、四
采样频率、时间、声道、量化与储存大学的关系
2.实现方案
1.方案一:FIFO的思想
2.方案二:RAM的思想
3.硬件实现
1.FPGA最小系统
2.I2S输入和输出接口
3.I2C接口
4.代码结构及实现
1.整体端口
module I2S_64K
(//main controllerinput i_rst,input i_bit_clk, input i_fs_clk,output o_data,//adc output reg o_bit_clk,output reg o_fs_clk,output o_main_clk, //---------------------------------->now, it have not be useddinput i_data0,input i_data1,input i_data2,input i_data3,//input i_data4,//input i_data5//i2c_config_done//input i2c_config_done
);
2.生成ADC芯片的Fbclk1和Flsclk1
parameter DIVIDE=4; //共4路数据,所以4分频
//**********************************************************************************************************************
//************************ o_bit_clk = i_bit_clk / DIVIDE ; o_fs_clk = i_fs_clk / DIVIDE *************************
//**********************************************************************************************************************
//1.o_bit_clk = i_bit_clk / DIVIDE
reg [1:0] cnt_bit_divide;always@(negedge i_bit_clk or negedge i_rst) //下降沿时钟触发是为了下降沿和o_fs_clk对齐
if(!i_rst)begincnt_bit_divide <= 2'd0;o_bit_clk <= 1'b0;end
else if(cnt_bit_divide == (DIVIDE/2-1)) begincnt_bit_divide <= 2'd0;o_bit_clk <= ~o_bit_clk;end
elsebegincnt_bit_divide <= cnt_bit_divide + 1'b1;o_bit_clk <= o_bit_clk;end//**********************************************
//2.o_fs_clk = i_fs_clk / DIVIDE
reg [1:0] cnt_fs_divide;always@(negedge i_fs_clk or negedge i_rst)
if(!i_rst)begincnt_fs_divide <= 2'd0;o_fs_clk <= 1'b1; end
else if(cnt_fs_divide == (DIVIDE/2-1)) begincnt_fs_divide <= 2'd0;o_fs_clk <= ~o_fs_clk;end
elsebegincnt_fs_divide <= cnt_fs_divide + 1'b1;o_fs_clk <= o_fs_clk;end
3.生成ADC芯片的Fmclk
wire clkout_o,lock_o;GW_PLL PLL_3(.clkout(clkout_o), //output clkout.lock(lock_o), //output lock.clkin(i_bit_clk) //input clkin);
assign o_main_clk = (lock_o == 1'b1) ? clkout_o : 1'b0;
4.I2S接收电路和4路并行数据写入RAM(写入时钟Fbclk1)
1.接收电路上升沿时钟便要检测和下降沿时钟开始接收数据
// dectect o_fs_clk edge change
reg o_fs_clk1,o_fs_clk2;always@(posedge o_bit_clk or negedge i_rst)
if(!i_rst)begino_fs_clk1 <= 1'b0;o_fs_clk2 <= 1'b0;end
else begino_fs_clk1 <= o_fs_clk;o_fs_clk2 <= o_fs_clk1;endwire wsp = o_fs_clk1 ^ o_fs_clk2; // edge detect
2.接收数据写入RAM
//*******************************************
// SRAM store count register
reg [4:0] cnt_rec; //SRAM store count register always@(negedge o_bit_clk or negedge i_rst) //下降沿时钟,wsp上升沿开始计时(see the I2S bus specification.pdf,the last two figure)
if(!i_rst)begincnt_rec <= 5'd0; end
else if(wsp) //begincnt_rec <= 5'd1; end
elsebegincnt_rec <= cnt_rec + 1'b1; end
RAM写入使能,RAM写入就是一个周期,即立马写入
//*******************************************
// SRAM write enable signal
wire cea1 = o_fs_clk;
wire cea2 = ~ o_fs_clk;
RAM数据写入并编通道号
//*******************************************
//ADC data receive ,then store the data in SRAM ,
wire [3:0] data_adc;
//assign data_adc = {i_data0,i_data1,i_data2,i_data3};assign data_adc = ((cnt_rec >= 5'd25) | (cnt_rec <= 5'd20)) ? {i_data0,i_data1,i_data2,i_data3} :((cea1 == 1'b1) & (cnt_rec == 5'd21)) ? (4'b0000) :((cea1 == 1'b1) & (cnt_rec == 5'd22)) ? (4'b0001) :((cea1 == 1'b1) & (cnt_rec == 5'd23)) ? (4'b0110) :((cea1 == 1'b1) & (cnt_rec == 5'd24)) ? (4'b1010) :((cea1 == 1'b0) & (cnt_rec == 5'd21)) ? (4'b0001) :((cea1 == 1'b0) & (cnt_rec == 5'd22)) ? (4'b1110) :((cea1 == 1'b0) & (cnt_rec == 5'd23)) ? (4'b0110) :((cea1 == 1'b0) & (cnt_rec == 5'd24)) ? (4'b1010) : (4'b0000);
5.主控CPU读出RAM(读RAM时钟Fbclk0)
1.读时钟边沿检测
reg i_fs_clk1,i_fs_clk2;always@(posedge i_bit_clk or negedge i_rst)
if(!i_rst)begini_fs_clk1 <= 1'b0;i_fs_clk2 <= 1'b0;end
else begini_fs_clk1 <= i_fs_clk;i_fs_clk2 <= i_fs_clk1;endwire wsp3 = i_fs_clk1 ^ i_fs_clk2; //边沿检测
2.读RAM的计数器
reg [4:0] cnt_read; //计数器只是用来计数,当o_bit_clk变化时它就清零,然后依次加一
always@(negedge i_bit_clk or negedge i_rst) //the same resson as 99 line
if(!i_rst)begincnt_read <= 5'd0;end
else if(wsp3) //i_fs_clk edge detect begincnt_read <= 5'd3; // attention !!! here is important, to keep same with the left-justified audio data end
else begin cnt_read <= cnt_read + 1'b1;end
3.读出的4个通道数据区分
reg [3:0] cnt_read_cnt; //这个累加器是为了把o_fs_clk分成四份,用来区别通道数的
always@(negedge i_bit_clk or negedge i_rst) //the same resson as 99 line
if(!i_rst)begincnt_read_cnt <= 4'b0000;end
else if((cnt_read == 5'd0) & (cnt_rec != 5'd31)) //begin cnt_read_cnt <= cnt_read_cnt << 1;end
else if((cnt_read == 5'd0) & (cnt_rec == 5'd31)) //begin cnt_read_cnt <= 4'b0001; //attention !!! here is delay for a i_bit_clk period !end
elsebegincnt_read_cnt <= cnt_read_cnt;end
4.读RAM使能
reg ceb11,ceb22;always@(negedge i_bit_clk or negedge i_rst) //the same resson as 99 line
if(!i_rst)beginceb11 <= 1'b0;ceb22 <= 1'b0;end
else if((cnt_read == 5'd30) & (cnt_rec == 5'd31) & (o_fs_clk == 1'b1) ) // here is good ,and there are no delay ,begin ceb11 <= 1'b1;ceb22 <= 1'b0;end
else if((cnt_read == 5'd30) & (cnt_rec == 5'd31) & (o_fs_clk == 1'b0) ) //begin ceb11 <= 1'b0;ceb22 <= 1'b1;end
elsebeginceb11 <= ceb11;ceb22 <= ceb22;end
6.两个RAM例化
GW_SDP sram_left(.dout(data_sram1), //output [3:0] dout read.clka(o_bit_clk), //input clka write.cea(cea1), //input cea write.reseta(!i_rst), //input reseta write.clkb(!i_bit_clk), //input clkb read.ceb(ceb11), //input ceb read.resetb(!i_rst), //input resetb read.oce(1'b0), //input oce .ada(cnt_rec), //input [4:0] ada write.din(data_adc), //input [3:0] din write.adb(cnt_read) //input [4:0] adb read);GW_SDP sram_right(.dout(data_sram2), //output [3:0] dout read.clka(o_bit_clk), //input clka write.cea(cea2), //input cea write.reseta(!i_rst), //input reseta write.clkb(!i_bit_clk), //input clkb read.ceb(ceb22), //input ceb read.resetb(!i_rst), //input resetb read.oce(1'b0), //input oce .ada(cnt_rec), //input [4:0] ada write.din(data_adc), //input [3:0] din write.adb(cnt_read) //input [4:0] adb read);
7.I2S数据输出
assign o_data = (ceb11 & (cnt_read_cnt == 4'b0001))? data_sram1[3] :(ceb11 & (cnt_read_cnt == 4'b0010))? data_sram1[2] :(ceb11 & (cnt_read_cnt == 4'b0100))? data_sram1[1] :(ceb11 & (cnt_read_cnt == 4'b1000))? data_sram1[0] :(ceb22 & (cnt_read_cnt == 4'b0001))? data_sram2[3] :(ceb22 & (cnt_read_cnt == 4'b0010))? data_sram2[2] :(ceb22 & (cnt_read_cnt == 4'b0100))? data_sram2[1] :(ceb22 & (cnt_read_cnt == 4'b1000))? data_sram2[0] : 1'b0;
5.modelsim仿真
6.总结
1.知识点
FPGA的I2S采集数据处理相关推荐
- 202- K7 +C6678学习资料:基于TI DSP TMS320C6678、Xilinx K7 FPGA XC7K325T的高速数据处理核心板
基于TI DSP TMS320C6678.Xilinx K7 FPGA XC7K325T的高速数据处理核心板 一.板卡概述 该DSP+FPGA高速信号采集处理板由我公司自主研发,包含一片TI DSP ...
- 202-基于TI DSP TMS320C6678、Xilinx K7 FPGA XC7K325T的高速数据处理核心板
基于TI DSP TMS320C6678.Xilinx K7 FPGA XC7K325T的高速数据处理核心板 一.板卡概述 该DSP+FPGA高速信号采集处理板由我公司自主研发,包含一片TI DSP ...
- FPGA控制AD7768采集
1.1 FPGA控制AD7768采集 1.1.1 本节目录 1)本节目录: 2)本节引言: 3)FPGA简介: 4) FPGA控制AD7768采集: 5)结束语. 1.1.2 本节引言 "不 ...
- FPGA实现AD采集
1 理论学习(废话篇) ADC 模拟数字转换器(额谈到这个,真的很荣幸在ADI实习的时光,打住不扯了),凡是涉及到模拟信号转数字信号的时候,都会用到ADC. ADC的种类很多,有积分型,逐次比 ...
- C6678板卡学习资料:202-基于TI DSP TMS320C6678、Xilinx K7 FPGA XC7K325T的高速数据处理核心板
一.板卡概述 该DSP+FPGA高速信号采集处理板由我公司自主研发,包含一片TI DSP TMS320C6678和一片Xilinx FPGA K7 XC72K325T-1ffg900.包含1个千兆网口 ...
- 直升机FPGA多路视频采集叠加OSD字符VGA-HDMI-DVI-SDI采集融合板卡设计
视频融合技术是虚拟现实技术的一个分支,也可以说是虚拟现实的一个发展阶段.视频融合技术指将一个或多个由视频采集设备采集的关于某场景或模型的图像序列视频与一个与之相关的虚拟场景加以融合,以生成一个新的关于 ...
- FPGA对高速采集ADC(8路并行数据)进行峰值检测,并记录峰值位置
本模块主要是ADC(2Gsps)采集信号波形进行峰值检测,主要是检测单音信号或者脉冲信号中的所有峰峰值信号(对噪声大信号适用性不是很好),并记录峰值点的位置. 1. 峰值检测8路并行数据端口 modu ...
- 基于fpga的单线激光雷达数据处理
激光雷达: 首先来给大家稍微介绍以下激光雷达,激光雷达,即Light Detation and ranging,它相比于其他雷达,优点非常明确,包括 1).具有极高的分辨率: 2).抗干扰能力强: 3 ...
- 【ESP32音视频传输】②通过I2S采集SPH0645麦克风音频数据并上传到服务端实时播放
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.I2S型麦克风SPH0645 二.使用步骤 1.连线图 2.Arduino主文件代码 3.服务端利用UDP接收音频 ...
- TC260-001《汽车采集数据处理安全指南》
来源:信安标委
最新文章
- bzoj千题计划303:bzoj4827: [Hnoi2017]礼物
- 北京大学AI写作机器人来了,会替代记者?
- NOI前总结:点分治
- 本地环境用eclipse搭建spring源码环境
- 查看docker容器日志
- 谈一谈自己对依赖、关联、聚合和组合之间区别的理解
- 【Python】python学习笔记day1
- matlab图片包微盘,如何用Matlab绘制二维图形资料下载
- Web Activities 简介
- DeadObjectException
- C#中的==、Equal、ReferenceEqual
- 使用阿帕奇服务器配置多个网站站点的方法
- cms php 免费,十大免费PHP内容管理系统(CMS)
- Spring Cloud与Dubbo怎么选择?
- 阿里云---云开发平台的创建与部署
- React Native仿美团下拉菜单
- Linux 用ssh远程登录及scp传输文件
- 中国金融科技50强之“百度金融”技术基因研究
- 台灯的品质,决定了你的阅读质量
- cGAN/cDCGAN,MNIST数据集初体验(内含原理,代码)
热门文章
- Office 2016 简体中文批量授权版镜像下载
- 《极客时间:代码精进之路》学习笔记
- php基础教程 第五章,VFP基础教程 第五章 创建查询和视图
- win10 联想键盘快捷键关闭_如何关闭联想台式机电脑USB键盘的FN功能
- kali局域网扫描ip_kali 扫描局域网的QQ
- 诺顿误杀事件造成“疑似病毒大爆发”恐慌
- 计算机维护工作周报,运维周报怎么写呀,这一周没什么事做
- 2022年6月25日PMP考试通关宝典-5
- PHP/PHPStudy所需的VC9-VC14的运行库
- 数模美赛准备——Numpy