【FPGA练习】(一): UART串口通信实验

2023-05-16

由于之前学习FPGA的过程中,没有做一个良好的记录,以及已学知识的扩展,所以从今天开始每一个实验例程和扩展应用,都要做文档记录。本实验,是基于正点原子达芬奇xc7a35tfgg484-2开发板。开发板时钟为50Mhz,采用RS232的通信协议。

1.UART串口通信简介

        串口数据的发送与接收都是基于帧结构的,即一帧一帧的发送与接收数据。每一帧除了中间包含8bit有效数据外,还在每一帧的开头都必须要有一个起始位,且固定为0;在每一帧的结束时,也必须要有一个停止位,且固定为1,即最基本的帧结构(不包括校验等)有10bit。在不发送或不接收数据的情况下,rx和tx处于空闲状态,此时rx和tx都保持高电平。

        后续则在上述实验原理的基础下,完成以下两个实验。

2.实验一:回环测试

        输入回环测试,即输入即输出。当上位机通过串口调试工具发送数据给FPGA,FPGA再通过串口接收数据并将接收到的数据返送给上位机,完成串口数据回环。

2.1.串口接收模块

        串口发送模块将输入的8位并行数据进行串行输出。串口发送模块uart_rx代码如下:

module uart_rx
#(
	parameter	UART_BPS		=	'd19200,
	parameter	CLK_FREQ		=	'd50_000_000
)
(
	input	wire				sys_clk,
	input	wire				sys_rst_n,
	input	wire				rx,
	
	output	reg		[7:0]		Po_data,
	output	reg					Po_flag
);
	parameter		BAUD_CNT_MAX = CLK_FREQ/UART_BPS ;

	reg					rx_reg1;
	reg					rx_reg2;
	reg					rx_reg3;
				
	reg					start_nedge;
	reg					work_en;
	reg		[15:0]		baud_cnt;
	reg					bit_flag;
				
	reg		[3:0]		bit_cnt;
	reg		[7:0]		rx_data;
	reg					rx_flag;
	
	//插入两级寄存器进行数据同步,用来消除亚稳态
	always@(posedge sys_clk or negedge sys_rst_n)begin
		if(sys_rst_n == 1'b0)
			rx_reg1	<=	1'b1;
		else
			rx_reg1 <=	rx;
	end
	
	always@(posedge	sys_clk	or negedge	sys_rst_n)begin
		if(sys_rst_n == 1'b0)
			rx_reg2 <= 	1'b1;
		else
			rx_reg2	<=	rx_reg1;
	end
	
	always@(posedge sys_clk or negedge sys_rst_n)begin
		if(sys_rst_n == 1'b0)
			rx_reg3	<=	1'b1;
		else
			rx_reg3 <=	rx_reg2;
	end
	
	always@(posedge sys_clk	or	negedge sys_rst_n)begin
		if(sys_rst_n == 1'b0)
			start_nedge <= 1'b0;
		else	if(rx_reg2 == 1'b0 && rx_reg3 == 1'b1)
			start_nedge	<=	1'b1;
		else
			start_nedge <=	1'b0;
	end
	
	always@(posedge	sys_clk	or negedge	sys_rst_n)begin
		if(sys_rst_n == 1'b0)
			work_en	<=	1'b0;
		else	if((bit_cnt	==	4'd8) && (bit_flag == 1'b1))
			work_en	<=	1'b0;
		else	if(start_nedge	==	1'b1)
			work_en	<=	1'b1;
	end
	
	
	always@(posedge	sys_clk	or negedge sys_rst_n)begin
		if(sys_rst_n == 1'b0)
			baud_cnt	<=	16'd0;
		else	if((baud_cnt	==	BAUD_CNT_MAX - 1'b1) || (work_en == 1'b0))
			baud_cnt 	<=	16'd0;
		else	if(work_en == 1'b1)
			baud_cnt	<=	baud_cnt + 1'b1;
	end
	
	always@(posedge	sys_clk	or	negedge sys_rst_n)begin
		if(sys_rst_n == 1'b0)
			bit_flag	<=	1'b0;
		else	if(baud_cnt	==	BAUD_CNT_MAX/2 - 1)
			bit_flag	<=	1'b1;
		else
			bit_flag	<=	1'b0;
	end
	
	always@(posedge	sys_clk	or	negedge	sys_rst_n)begin
		if(sys_rst_n == 1'b0)
			bit_cnt		<=	4'd0;
		else	if((bit_flag == 1'b1) && (bit_cnt == 4'd8))
			bit_cnt		<=	4'd0;
		else	if(bit_flag	== 1'b1)
			bit_cnt		<=	bit_cnt + 1'b1;
	end
	
	always@(posedge	sys_clk	or	negedge	sys_rst_n)begin
		if(sys_rst_n == 1'b0)
			rx_data		<=	8'd0;
		else	if((bit_cnt	>=	4'd1) && (bit_cnt <= 4'd8) && (bit_flag == 1'b1))
			rx_data		<=	{rx_reg3,rx_data[7:1]};
	end

	always@(posedge	sys_clk	or	negedge	sys_rst_n)begin
		if(sys_rst_n == 1'b0)
			rx_flag		<=	1'b0;
		else	if((bit_cnt == 4'd8) && (bit_flag == 1'b1))
			rx_flag		<=	1'b1;
		else
			rx_flag		<=	1'b0;
	end
	
	always@(posedge sys_clk or negedge sys_rst_n)begin
		if(sys_rst_n == 1'b0)
			Po_data	<=	8'b0;
		else	if(rx_flag	==	1'b1)
			Po_data	<=	rx_data;
	end
	
	always@(posedge	sys_clk or negedge	sys_rst_n)begin
		if(sys_rst_n == 1'b0)
			Po_flag	<=	1'b0;
		else
			Po_flag	<=	rx_flag;
	
	end
endmodule

验证仿真tb_ uart_rx.v如下所示

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2022/06/12 19:20:12
// Design Name: 
// Module Name: tb_uart_rx
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module tb_uart_rx();

reg					sys_clk		;
reg					sys_rst_n	;
reg					rx			;

wire	[7:0]		Po_data		;
wire				Po_flag		;

initial	begin
	sys_clk		 =	1'b1;
	sys_rst_n	<=	1'b0;
	rx			<=	1'b1;
	#20
	sys_rst_n	<=	1'b1;
end

initial	begin
	#200
	rx_bit(8'd0);
	rx_bit(8'd1);
	rx_bit(8'd2);
	rx_bit(8'd3);
	rx_bit(8'd4);
	rx_bit(8'd5);
	rx_bit(8'd6);
	rx_bit(8'd7);
end

always #10 sys_clk = ~sys_clk;

task	rx_bit(input	[7:0]	data);

	integer	i;//定义一个常亮
	
	for(i=0;i<10;i=i+1)begin
		case(i)
			0 : rx <= 1'b0;
			1 : rx <= data[0];
			2 : rx <= data[1];
			3 : rx <= data[2];
			4 : rx <= data[3];
			5 : rx <= data[4];
			6 : rx <= data[5];
			7 : rx <= data[6];
			8 : rx <= data[7];
			9 : rx <= 1'b1;
		endcase
		#(5208 * 20); // 每发送1位数据延时5208个时钟周期
	end
	
endtask

uart_rx		uart_rx_inst(
	.sys_clk	(sys_clk	),
	.sys_rst_n	(sys_rst_n	),
	.rx			(rx			),

	.Po_data	(Po_data	),
	.Po_flag	(Po_flag	)
);

endmodule

2.2.串口接收模块

        串口接收模块将串行的8位数据转化为并行的8位数据进行输出。串口接收模块uart_rx代码如下:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2022/06/12 16:13:31
// Design Name: 
// Module Name: uart_tx
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//

module uart_tx
#(
	parameter				UART_BPS	= 	'd9600,
	parameter				CLK_FREQ	=	'd50_000_000
)
(
	input	wire			sys_clk	,
	input	wire			sys_rst_n,
	input	wire	[7:0]	Po_data	,
	input	wire			Po_flag	,
	
	output	reg				tx			
);

	parameter			BAUD_CNT_MAX	=	CLK_FREQ / UART_BPS;

	reg		[15:0]		baud_cnt;
	reg					bit_flag;
	reg		[3:0]		bit_cnt;
	reg					work_en;
	
	always@(posedge sys_clk or negedge sys_rst_n)begin
		if(sys_rst_n == 1'b0)
			baud_cnt	<=	16'd0;
		else	if((baud_cnt == BAUD_CNT_MAX - 1) || (work_en == 1'b0))
			baud_cnt	<=	16'd0;
		else	if(work_en == 1'b1)
			baud_cnt	<=	baud_cnt + 1'b1;
	end
	
	always@(posedge sys_clk or negedge sys_rst_n)begin
		if(sys_rst_n == 1'b0)
			work_en		<=	1'b0;
		else	if((bit_flag == 1'b1) && (bit_cnt == 4'd9))
			work_en		<=	1'b0;
		else	if(Po_flag == 1'b1)
			work_en		<=	1'b1;
	end
	
	always@(posedge	sys_clk or negedge sys_rst_n)begin
		if(sys_rst_n == 1'b0)
			bit_flag	<=	1'b0;
		else	if(baud_cnt	==	16'd1)
			bit_flag	<=	1'b1;
		else
			bit_flag	<=	1'b0;
	end
	
	always@(posedge	sys_clk or negedge sys_rst_n)begin
		if(sys_rst_n == 1'b0)
			bit_cnt	<=	4'd0;
		else	if((bit_flag == 1'b1) && (bit_cnt == 4'd9))
			bit_cnt	<=	4'd0;
		else	if((bit_flag == 1'b1) && (work_en == 1'b1))
			bit_cnt	<=	bit_cnt	+ 1'b1;
	end
	
	always@(posedge	sys_clk	or negedge	sys_rst_n)begin
		if(sys_rst_n == 1'b0)
			tx	<=	1'd1;
		else	if(bit_flag == 1'b1)
			case(bit_cnt)
				4'd0	:	tx	<=	1'b0;
				4'd1	:	tx	<=	Po_data[0];
				4'd2	:	tx	<=	Po_data[1];
				4'd3	:	tx	<=	Po_data[2];
				4'd4	:	tx	<=	Po_data[3];
				4'd5	:	tx	<=	Po_data[4];
				4'd6	:	tx	<=	Po_data[5];
				4'd7	:	tx	<=	Po_data[6];
				4'd8	:	tx	<=	Po_data[7];
				4'd9	:	tx	<=	1'b1;
				default	:	tx	<=	1'b1;
			endcase
	end
	
	
endmodule

2.3.顶层模块

        顶层模块即将uart_rx.v和uart_tx.v两个连接起来即可。

module rs232
(
	input	wire				sys_clk,
	input	wire				sys_rst_n,
	input	wire				rx,
	
	output	wire				tx
);

wire	[7:0]		Po_data;
wire				Po_flag;

parameter	UART_BPS		=	16'd19200			;
parameter	CLK_FREQ		=	26'd50_000_000		;

uart_rx		
#(
	.UART_BPS	(UART_BPS	),
	.CLK_FREQ	(CLK_FREQ	)
)
uart_rx_inst
(
	.sys_clk	(sys_clk	),
	.sys_rst_n	(sys_rst_n	),
	.rx			(rx			),

	.Po_data	(Po_data	),
	.Po_flag	(Po_flag	)
);

uart_tx	
#(
	.UART_BPS	(UART_BPS	),
	.CLK_FREQ	(CLK_FREQ	)
)
uart_tx_inst
(
	.sys_clk		(sys_clk)	,
	.sys_rst_n		(sys_rst_n)	,
	.Po_data		(Po_data)	,
	.Po_flag		(Po_flag)	,
			        
	.tx				(tx)
);


endmodule

3.实验二:检测字符

        当上位机通过串口调试工具发送数据给FPGA,FPGA进行检测识别,发现传送的数据为Hello Word时,串口返回ni hao,并点亮led灯;否则,串口返回no,Led熄灭;

2.1.串口发送和接收模块

        串口的发送和接收模块都和之前的模块保持一致,直接调用之前的模块即可。

2.3.控制模块

        控制模块uart_ctrl用于控制串口通信发送使能和发送数据信号,当检测到上位机串口调试工具助手发送数据给FPGA时,FPGA接收模块接收数据后与Hello Word进行对标,发现一致,将ni hao发送到上位机,并点亮led灯;当接收到的数据不一致时,测返回no,并熄灭led灯。控制模块uart_ctrl代码如下:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【FPGA练习】(一): UART串口通信实验 的相关文章

  • 【工具】记录安装Zsh

    本文主要记录下安装Zsh的过程 xff0c 方便后续换设备安装 xff01 与大家共同学习 xff01 xff08 Ubuntu 20 04 xff09 安装zsh sudo apt install zsh 2 下载oh my zsh 并安
  • 【Ubuntu】记录Ubuntu缺少启动项问题

    今天突然发现自己装的Ubuntu没有启动项 xff0c 也就是没有那个EFI分区 xff0c 人都麻了 xff01 原因是先把装Ubuntu的固态拿了出来 xff0c 再装的win11 xff0c 结果win11可以用了 xff0c Ubu
  • 【SLAM学习】基于Pangolin绘制运动轨迹

    Pangolin库 是一个轻量级的跨平台视图控制库 xff0c 主要用于可视化 交互和调试三维数据 该库提供了一系列图形界面工具 xff0c 包括窗口 OpenGL渲染器 3D相机 图像显示等 xff0c 可以方便地进行三维数据可视化和交互
  • Groovy学习-IO/文件操作

    读取文件 读取文本文件并打印每一行文本 new File 39 39 39 a txt 39 eachLine line gt println line eachLine方法是Groovy为File类自动添加的方法 xff0c 同时提供多个
  • linux---线程池种类以及实现(固定数量)

    线程池是什么 一堆固定的数量的或者有最大数量限制的线程 43 任务队列 gt 用于我们并发处理请求 xff0c 避免了大量频繁的线程的创建和销毁的事件成本 xff0c 同时避免了峰值压力带来瞬间大量线程被创建资源耗尽 xff0c 程序奔溃的
  • 什么是线程池?为什么使用线程池?

    1 什么是线程池 xff1f 线程池和数据库连接池非常类似 xff0c 可以统一管理和维护线程 xff0c 减少没有必要的开销 2 为什么要使用线程池 xff1f 因为频繁的开启线程或者停止线程 xff0c 线程需要重新从cpu从就绪状态调
  • Java实现List按条件分成多个子List

    一 业务场景 相信很多开发的小伙伴都有遇到过需要对表按特定条件进行查询 xff0c 然后再进行归类 xff0c 比如 xff1a 对员工表进行检索 xff0c 然后分别按他们所在的部门进行归类 xff0c 一般的做法都是按部门唯一标识 xf
  • MySQL生成随机姓名

    CREATE DEFINER 61 96 root 96 64 96 localhost 96 FUNCTION 96 rand name 96 n int RETURNS varchar 16 CHARSET utf8 begin 初始化
  • RabbitMQ的安装教程

    本文介绍RabbitMQ在Linxu上的安装教程 一 下载相关安装包 相应的安装包可以从官网上 xff08 https www rabbitmq com xff09 进行下载 xff0c 也可以从我的网盘上下载 蓝奏云地址 xff1a ht
  • SpringBoot实现广州健康通疫苗预约提醒

    一 前言 终于轮到了打第二针疫苗的时候 xff0c 无奈每次打开 广州健康通 或 粤康通 小程序 xff0c 每次都是被预约完的状态 xff0c 广州人口众多 xff0c 说不定有很多人一直守在小程序前等着放号 xff0c 所以这篇文章就诞
  • 搭建SFTP服务器实现文件上传

    1 前言 最近一直在做数据迁移接口的开发 xff0c 涉及到大文件的远程下载与上传 xff0c 其实倒没有什么原理可言 xff0c 无非就是两台机器互连之后 xff0c 获得文件流然后进行传输 xff0c 不过在这过程也遇到过一些小坑 xf
  • SpringBoot整合RabbitMQ实现五种消息模型

    一 什么是消息队列 xff1f 消息 xff0c 可以理解为两个应用之间传递的数据 xff0c 数据可以是基本数据类型 xff0c 也可以是对象等 消息队列 xff0c 则是容器 xff0c 生产者产生的消息存放在这个容器里面 MQ的整个过
  • SpringBoot整合CXF框架实现Webservice服务端

    1 前言 近期接手一个10多年的老项目 xff0c 敲重点 xff0c 10多年 xff01 xff01 xff01 就是最纯粹的servlet技术 xff0c 貌似是从2008年运维到现在 xff0c 老项目终究会有被淘汰的这一天 xff
  • Windows下切换不同版本JDK

    1 前言 从四月份重新入职新公司以来 xff0c 主要负责两个项目的开发 xff0c 一个是10多年前的项目 xff0c 一个是2019年开始开发的项目 xff0c 这两个项目依赖于不同版本的JDK xff0c 一个是JDK6 xff0c
  • css实现圆形div旋转,如“已预约”效果

    lt DOCTYPE html gt lt html gt lt head gt lt meta charset 61 34 utf 8 34 gt lt title gt lt title gt lt head gt lt style g
  • c++---类和对象(六大默认成员函数)

    类中默认的六个成员函数构造函数析构函数拷贝构造函数赋值操作符重载取地址和const取地址操作符重载const成员函数 1 类中默认的六个成员函数 首先看看下面代码 class A int main A a return 0 这个代码并没有报
  • 微服务系列--nacos注册中心与服务发现

    1 前言 终究还是到了更新关于微服务相关博客的时候了 xff0c 经过挺长一段时间微服务的自主学习 xff0c 现在不敢说自己熟悉微服务 xff0c 但我也能略知一二 微服务嘛 xff0c 其实入门之后便会发现 xff0c 其实关于微服务相
  • 微服务系列--Ribbon负载均衡

    1 前言 这篇文章接上一篇文章进行开发 xff0c 上一篇整合完了Nacos xff0c 这篇来整合Ribbon Ribbon不属于SpringCloud Alibaba的东西 xff0c 而是基于Netflix Ribbon实现的 可以让
  • Centos7安装Jenkins

    将Jenkins存储库添加到yum repos xff0c 并安装Jenkins sudo wget O etc yum repos d jenkins repo http pkg jenkins ci org redhat jenkins
  • Jenkins自动化部署SpringBoot项目

    首先需要安装所需的两个插件 xff0c Maven Integration plugin 和 Publish Over SSH 在 系统配置 xff0c 将服务器信息配置到jenkins xff0c 我用的是腾讯云服务器 xff0c 所以将

随机推荐

  • 优雅关闭SpringBoot项目-接口方式

    前言 一般在服务器重新部署SpringBoot项目 xff0c 无非就是用kill 9暴力停止进程 xff0c 但会造成很多数据问题 xff0c 如果遇到一些耗时或者正在处理交易类的业务时 xff0c 直接导致数据异常 xff0c 严重会导
  • Linux安装Jenkins

    前言 现在Jenkins的最新版本都需要基于JDK11以上才能够正常使用 xff0c 不然会出现各种插件安装不上的问题 又不想安装JDK11 xff0c 想继续用JDK8 xff0c 只能通过指定安装符合JDK8的Jenkins版本 PS
  • rosdep update出错解决办法(2021)

    ROS安装方法 xff1a ros安装后 xff0c 初始化时rosdep update出错解决办法 2021 06 30 初始化时rosdep update出错解决办法 2021年以前 xff0c 通过科学上网 手机开热点等方式 xff0
  • 0x0FA23729 (vcruntime140d.dll)处(位于 类和对象-封装.exe 中)引发的异常(已解决)

    运行程序的时候第42行 抛出异常 xff0c 但是我将该cpp文件放到别的解决方案下就不会出异常 include lt iostream gt include lt string gt using namespace std class P
  • Win10 摄像头:由于其配置信息(注册表中的)不完整或已损坏,Windows无法启动这个硬件设备.【未解决完全】

    问题描述 xff1a 刚刚重装完win10系统之后 xff0c 出现无法打开摄像头的问题 xff0c 解决方法 xff1a 通过修改注册表中得相关信息进行解决 首先打开设备管理器 xff0c 找到设备的类Guid记录下Guid 的值 如此处
  • 2021年总结与2022年展望

    一 工作和学习 通过调剂 xff0c 正式成为了一名研究生 xff0c 结束了自己两年的考研备考 xff0c 不知道是好还是坏 xff0c 看到周围朋友考的时候心里还是会有点失落感 在一家通信设备公司实习软件测试 xff0c 收获很多 xf
  • 计算机网络---网络基础(TCP/IP五层模型,数据的封装和分用)

    认识网络中常用的名词以及基本的概念熟悉OSI七层模型和TCP IP五层模型理解网络通信的数据传输流程 认识网络中常用的名词 ip地址 ip地址就是表示我们一台主机的因为数字不好记忆 xff0c 通常使用点分十进制表示IP xff0c 每条数
  • C语言简易TCP服务端程序

    C语言TCP服务端程序 文章目录 C语言TCP服务端程序项目介绍关键技术代码实现一请求一线程方式epoll方式实现多个客户端连接的TCP服务端程序epoll的水平触发和边缘触发 完整代码编译和启动使用NetAssist测试 项目介绍 本项目
  • C++使用gRPC实例

    什么是gRPC RPC 即远程过程调用协议 xff08 Remote Procedure Call Protocol xff09 xff0c 可以让我们像调用本地对象一样发起 远程调用 RPC 凭借其强大的治理功能 xff0c 成为解决分布
  • 复睿智行CC++开发实习面试

    线上面试 xff0c HR和一位技术的面试官 自我介绍 现在研究生学习的方向是什么 xff1f 我还去答区块链 xff0c 本来就半桶水 xff0c 还不如直接回答C C 43 43 后端这个方向 大数据分析这一块有做过吗 xff1f 我
  • 经纬恒润LinuxC++日常实习面经

    自我介绍 在学校成绩如何 xff0c 有没有获得奖学金 xff0c 考研的时间等等相关问题 能实习多久 xff0c 研究生研究的方向 你这个LinuxC 43 43 开发的学习是自学的吗 xff0c 怎样的自学途径 我 xff1a 看书 看
  • 集群聊天服务器项目(三)——负载均衡模块与跨服务器聊天

    负载均衡模块 为什么要加入负载均衡模块 原因是 xff1a 单台服务器并发量最多两三万 xff0c 不够大 负载均衡器 Nginx的用处或意义 xff08 面试题 xff09 把client请求按负载算法分发到具体业务服务器Chatserv
  • C++校招面试题

    C 43 43 static关键字的作用 xff08 从elf结构 链接的过程 xff09 答 xff1a static可以修饰全局变量 函数 局部变量 xff0c 这些符号在加了staitc后就只能在当前文件可见 xff0c 其他文件不可
  • make_shared知识点

    背景 普通创建shared ptr的方法如 xff1a shared ptr span class token operator lt span span class token keyword int span span class to
  • emplace方法原理剖析

    emplace back 和 push back 的差别 有一个类Test定义如下 span class token keyword class span span class token class name Test span span
  • 【 rbx1翻译 第七章、控制移动基座】第八节、使用里程计进行往返运动

    7 8 Out and Back Using Odometry 使用里程计进行往返运动 现在 xff0c 我们了解了里程表信息是如何在ROS中表示的 xff0c 我们可以更精确地在往返过程中移动机器人 下一个脚本将监视 odom和 base
  • 项目总结一:串口通信 || 串口接收数据和写入的数据不一致

    在做项目串口通信时遇到一个奇怪的bug xff0c 我写入的一个两个字节short类型数据3 xff0c 接受到的数据很奇怪有时是一个很大的数 xff0c 有时又是300多 xff0c 为了找到原因也是废了一些时间 xff0c 这里给分享一
  • linux---套接字编程

    一 Socket是什么 1 socket套接字 xff1a socket起源于Unix xff0c 而Unix Linux基本哲学之一就是 一切皆文件 xff0c 都可以用 打开open gt 读写write read gt 关闭close
  • ROS订阅者只订阅一次消息

    include lt ros ros h gt include lt opencv2 core core hpp gt include lt opencv2 imgproc imgproc hpp gt include lt opencv2
  • 【FPGA练习】(一): UART串口通信实验

    由于之前学习FPGA的过程中 xff0c 没有做一个良好的记录 xff0c 以及已学知识的扩展 xff0c 所以从今天开始每一个实验例程和扩展应用 xff0c 都要做文档记录 本实验 xff0c 是基于正点原子达芬奇xc7a35tfgg48