FPGA学习笔记:数据采集传输系统设计(六):ADC采集FIFO缓存UART发送系统顶层及仿真

一、ADC采集FIFO缓存UART发送系统顶层模块设计

1.系统整体结构

在前一篇文章中已经设计了adc_fifo.v和fifo_uart_tx.v两个模块,实现了将连续AD采集数据存储到fifo、从fifo读取数据通过串口发送两部分功能,需设计顶层模块,将这两个模块和fifo模块连接,系统整体结构如下图所示
系统整体
顶层模块为adc_fifo.v和fifo_uart_tx.v提供Start信号,表示ADC连续采集开始,各模块执行对应功能。

2.顶层模块端口说明

端口名称方向说明
Clkinput系统时钟
Rst_ninput系统复位
Startinput开始采集数据并发送 标志位
AD_DoneoutputAD采集完成标志位
Uart_doneoutputUART发送完成标志位
uart_txoutput串口数据发送端
ADC_OUTinputADC串行数字信号
ADC_CS_NoutputADC片选
ADC_DINoutput串行数据送给ADC芯片
ADC_SCLKoutputADC时钟
ADC_Doneoutput单次AD采集完成标志位,可删除,仿真用

ADC_Done信号为单次AD采集完成标志位,在仿真时使用,板级验证时不需要该端口。
Start为ADC连续采集开始标志,由于ADC采集和UART速率不同,AD_Done表示ADC连续采集完成,Uart_done表示采集的所有数据发送完成。

3.顶层模块代码设计

module adc_data_send_top(
	input Clk,					//系统时钟
	input Rst_n,				//系统复位
	
	input Start,				//开始采集数据并发送 标志位
	output wire AD_Done,		//AD采集完成标志位
	output wire Uart_done,  	//UART发送完成标志位
	
	output wire uart_tx,		//串口数据发送端
	
	input ADC_OUT,				//ADC串行数字信号
	output wire ADC_CS_N,		//ADC片选
	output wire ADC_DIN,		//串行数据送给ADC芯片
	output wire ADC_SCLK,		//ADC时钟
	output wire ADC_Done		//单次AD采集完成标志位,可删除,仿真用
);
	
	wire [11:0] FIFO_DATA;
	wire [11:0] FIFO_Q;
	wire rdreq,wrreq,empty,full;
	
//ADC数据存入FIFO
	adc_fifo adc_fifo(
		.Clk(Clk),
		.Rst_n(Rst_n),
		.Start(Start),			//开始采集数据标志位
		.AD_Done(AD_Done),		//采集完成标志位
		
		.ADC_CS_N(ADC_CS_N),	
		.ADC_DIN(ADC_DIN), 	
		.ADC_SCLK(ADC_SCLK),	
		.ADC_OUT(ADC_OUT),	
		.ADC_Done(ADC_Done), 	//单次AD采集完成标志位,可删除,仿真用
		
		.full(full),			//FIFO满标志位
		.wrreq(wrreq),			//FIFO写使能
		.FIFO_DATA(FIFO_DATA)	//FIFO数据输入
	);

//FIFO缓存模块
	fifo data_fifo(
		.clock(Clk),
		.data(FIFO_DATA),
		.rdreq(rdreq),
		.sclr(!Rst_n),
		.wrreq(wrreq),
		.empty(empty),
		.full(full),
		.q(FIFO_Q)
	);

//将FIFO存储的ADC数据用串口发送
	fifo_uart_tx data_tx(
		.Clk(Clk),
		.Rst_n(Rst_n),
		.Start(Start),		//开始发送数据标志位
		
		.empty(empty),		//FIFO空标志位
		.FIFO_Q(FIFO_Q),	//FIFO数据输入
		.rdreq(rdreq),		//FIFO读使能
		.Uart_done(Uart_done),
		.uart_tx(uart_tx)
	);
endmodule

二、ADC采集FIFO缓存UART发送系统仿真

1.ADC采集数据模拟

模拟ADC芯片采集过程,在SCLK下降沿时改变ADC_OUT的值,将这个过程封装成task任务。

	task GENE_ADC_OUT;//生成ADC数据
		input [15:0] v_data;
		integer i;
		begin
			wait(!ADC_CS_N);//等待CS_N被拉低
			for(i=0;i<16;i=i+1) begin
				@(negedge ADC_SCLK)
					ADC_OUT = v_data[15-i];
			end
		end
	endtask

2.PC串口接收模拟

将之前设计好的串口接收模块例化进来,在仿真时只需观测PC_uart_rx端口,查看接收到的数据和AD采集数据是否一致。

	uart_data_rx PC_rx(
		.Clk(Clk),
		.Rst_n(Rst_n),
		.rx(uart_tx),
		.baud_set(3'd2),		//波特率为9600
		.data(PC_uart_rx),
		.rx_done(PC_rx_done)
	);

3.仿真文件

利用repeat重复128次,调用GENE_ADC_OUT任务模拟生成AD采集的数据,等待单次AD采集结束(ADC_Done置1)后生成下一次数据

`timescale 1ns/1ns
module adc_data_send_top_tb();

	reg Clk,Rst_n;
	reg Start;//开始采集数据并发送 标志位
	wire AD_Done;//采集完成标志位
	
	reg ADC_OUT;
	reg [15:0] ADC_DATA_GEN;
	wire ADC_CS_N,ADC_DIN,ADC_SCLK;
	wire ADC_Done;
	
	wire uart_tx,Uart_done;
	wire [7:0] PC_uart_rx;

	adc_data_send_top adc(
		.Clk(Clk),
		.Rst_n(Rst_n),	
		.Start(Start),//开始采集数据并发送 标志位
		.AD_Done(AD_Done),//采集完成标志位
		.ADC_OUT(ADC_OUT),
		.ADC_CS_N(ADC_CS_N),
		.ADC_DIN(ADC_DIN),
		.ADC_SCLK(ADC_SCLK),
		.ADC_Done(ADC_Done),
		.Uart_done(Uart_done),
		.uart_tx(uart_tx)
	);

	uart_data_rx PC_rx(
		.Clk(Clk),
		.Rst_n(Rst_n),
		.rx(uart_tx),
		.baud_set(3'd2),		//波特率为9600
		.data(PC_uart_rx),
		.rx_done(PC_rx_done)
	);

	initial Clk = 1'b1;
	always #10 Clk = ~Clk;
	
	initial begin
		Rst_n = 1'b0;
		Start = 1'b0;
		ADC_OUT = 1'b0;
		ADC_DATA_GEN = 16'h0100;
		#201;
		Rst_n = 1'b1;
		#20;
		
		Start = 1'b1;#20;
		Start = 1'b0;#20;
		repeat(128) begin
			GENE_ADC_OUT(ADC_DATA_GEN);
			wait(ADC_Done);
			ADC_DATA_GEN = ADC_DATA_GEN + 8;
		end
		wait(AD_Done);
		wait(Uart_done);
		#200000;
		$stop;
	end

	task GENE_ADC_OUT;//生成ADC数据
		input [15:0] v_data;
		integer i;
		begin
			wait(!ADC_CS_N);//等待CS_N被拉低
			for(i=0;i<16;i=i+1) begin
				@(negedge ADC_SCLK)
					ADC_OUT = v_data[15-i];
			end
		end
	endtask
endmodule

4.仿真结果

整体波形:
在这里插入图片描述
前面红框的部分为AD采集过程,从仿真结果可以明显看出AD采集速率和串口传输速率的差异,因此在利用FPGA做高速AD采集项目时,必须先将采集数据缓存再通过串口发送,不缓存会影响采样速率或者导致采样数据丢失。
AD采集波形:
在这里插入图片描述
Start信号为1时,开始采集数据,采集到的第一个数据为16’h0100
在这里插入图片描述
采集到最后一个数据时,AD_Done置1,表示连续采集完成,最后一个数据为16’h04f8
串口发送波形:
在这里插入图片描述
采集到的第一个数据被存入fifo时,串口开始发送数据,观察第一个PC_rx_done脉冲后的数据,接收到了8’h01和8’h00,与AD采集到的第一个数据16’h0100一致。
在这里插入图片描述
采集到的最后两个数据为8’h04和8’hf8,与AD采集到的最后一个数据16’h04f8一致,发送完最后一个数据后,Uart_done置1,所有数据发送完毕

整个系统的文件及仿真文件下载链接:
FPGA数据采集传输系统

  • 8
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
项目背景1.1 AD转换 AD转换就是模数转换。顾名思义,就是把模拟信号转换成数字信号。主要包括积分型、逐次逼近型、并行比较型/串并行型、Σ-Δ调制型、电容阵列逐次比较型及压频变换型。 A/D转换器是用来通过一定的电路将模拟量转变为数字量。模拟量可以是电压、电流等电信号,也可以是压力、温度、湿度、位移、声音等非电信号。但在A/D转换前,输入到A/D转换器的输入信号必须经各种传感器把各种物理量转换成电压信号。 AD转换的技术指标,一般有如下几个: 1. 分辨率(Resolution) 指数字量变化一个最小量时模拟信号的变化量,定义为满刻度与2^n的比值。分辨率又称精度,通常以数字信号的位数来表示。 2. 转换速率(Conversion Rate)是指完成一次从模拟转换到数字的AD转换所需的时间的倒数。积分型AD的转换时间是毫秒级属低速AD,逐次比较型AD是微秒级属中速AD,全并行/串并行型AD可达到纳秒级。采样时间则是另外一个概念,是指两次转换的间隔。为了保证转换的正确完成,采样速率 (Sample Rate)必须小于或等于转换速率。因此有人习惯上将转换速率在数值上等同于采样速率也是可以接受的。常用单位是ksps和Msps,表 示每秒采样千/百万次(kilo / Million Samples per Second)。 3. 量化误差 (Quantizing Error) 由于AD的有限分辨率而引起的误差,即有限分辨率AD的阶梯状转移特性曲线与无限分辨率AD(理想AD)的转移特 性曲线(直线)之间的最大偏差。通常是1个或半个最小数字量的模拟变化量,表示为1LSB、1/2LSB。 4. 偏移误差(Offset Error) 输入信号为零时输出信号不为零的值,可外接电位器调至最小。 5. 满刻度误差(Full Scale Error) 满度输出时对应的输入信号与理想输入信号值之差。 6. 线性度(Linearity) 实际转换器的转移函数与理想直线的最大偏移,不包括以上三种误差。 其他指标还有:绝对精度(Absolute Accuracy) ,相对精度(Relative Accuracy),微分非线性,单调性和无错码,总谐波失真(Total Harmonic Distotortion缩写THD)和积分非线性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值