FPGA学习笔记_UART串口协议_串口接收端设计
FPGA学习笔记
1. UART串口协议以及串口接收端设计
1 原理图
2 Verilog 代码
3 Modelsim仿真
4. FPGA板级验证
1.1 串口协议接收端设计
- 目标:FPGA接收其他设备通过UART发送过来的数据。
- 实验现象:在Quartusz II中调用in system sources and probes
editor工具,查看UART接收模块接受到的数据,数据有pc机发出。 - 知识点:
- uart的通信协议原理和工业环境下的数据接受实现
- in system sources and probes editor(ISSP)调试工具的使用
1. 原理图
- 模块组成:
- 输入信号同步模块
- 起始数据检测模块
- 波特率产生模块
- 数据接受进程
(1). 发送端实验室数据采集时序图
- 实验室环境:采样一个数据的中点
(2). 发送端工业数据采集时序图
- 工业环境:工业环境的电磁干扰严重,噪音信号容易导致错误,只采样一次的数据不准确。
- 方法:采每位数据采样的中间6次的结果,根据这6次结果的电平(0,1)出现的次数,判定最终结果。
2. Verilog 代码
//----top---------------------------------------
module uart_rx_r0
(input clk,input rst_n,input rs232_rx,input [2:0] baud_set,output reg rx_done,
// output rx_state,output reg [7:0] data_byte
);reg rs232_rx_reg1;reg rs232_rx_reg2;reg rs232_rx_syn1;reg rs232_rx_syn2;reg uart_state;reg [8:0] div_cnt;reg [8:0] cnt_max;//div_cnt max valuereg baud_clk;reg [7:0] baud_cnt;reg [3:0] reg_data_byte [7:0];reg [2:0] START;reg [2:0] STOP;
// wire pos_edge;wire neg_edge;//----asynch rs232_rx--> synch-----------always@(posedge clk or negedge rst_n)if(!rst_n)beginrs232_rx_syn1 <= 0;rs232_rx_syn2 <= 0;end else beginrs232_rx_syn1 <= rs232_rx;rs232_rx_syn2 <= rs232_rx_syn1;end
//----start bit detect------------------always@(posedge clk or negedge rst_n)if(!rst_n)beginrs232_rx_reg1 <= 0;rs232_rx_reg2 <= 0;end else beginrs232_rx_reg1 <= rs232_rx_syn2;rs232_rx_reg2 <= rs232_rx_reg1;end
// assign pos_edge = (rs232_rx_reg1 & !rs232_rx_reg2);assign neg_edge = (!rs232_rx_reg1 & rs232_rx_reg2); //------baud_set------------------------always@(*)case(baud_set)3'd0: cnt_max <= 9'd325;3'd1: cnt_max <= 9'd163;3'd2: cnt_max <= 9'd81;3'd3: cnt_max <= 9'd54;3'd4: cnt_max <= 9'd27;default: cnt_max <= 9'd325;endcase
//----uart_state-------------------------always@(posedge clk or negedge rst_n)if(!rst_n)uart_state <= 0;else if(neg_edge)uart_state <= 1;else if(rx_done || (baud_cnt==12 && (START > 2))) uart_state <= 0;elseuart_state <= uart_state;
//----frequence div-->baud_clk-----------always@(posedge clk or negedge rst_n)if(!rst_n)div_cnt <= 0;else if(uart_state)beginif(div_cnt == cnt_max)div_cnt <= 0;elsediv_cnt <= div_cnt + 9'd1;end elsediv_cnt <= 0;always@(posedge clk or negedge rst_n)if(!rst_n)baud_clk <= 1'd0;else if(div_cnt == 9'd1)baud_clk <= 1'd1;elsebaud_clk <= 1'd0;
//----baud_cnt--------------------------always@(posedge clk or negedge rst_n)if(!rst_n)baud_cnt <= 0;else if(rx_done || (baud_cnt==12 && (START > 2)))baud_cnt <= 0;else if(baud_clk)baud_cnt <= baud_cnt + 8'd1;elsebaud_cnt <= baud_cnt;//----rx_done----------------------------always@(posedge clk or negedge rst_n)if(!rst_n)rx_done <= 1'b0;else if(baud_cnt == 8'd159)rx_done <= 1'b1;else rx_done <= 1'b0;//----data_byte--------------------------always@(posedge clk or negedge rst_n) // asynchronos transimiter, reg_data_byte is used to keep input data stable if(!rst_n)data_byte <= 8'd0;else if(baud_cnt == 8'd159)begindata_byte[0] <= reg_data_byte[0][2];data_byte[1] <= reg_data_byte[1][2];data_byte[2] <= reg_data_byte[2][2];data_byte[3] <= reg_data_byte[3][2];data_byte[4] <= reg_data_byte[4][2];data_byte[5] <= reg_data_byte[5][2];data_byte[6] <= reg_data_byte[6][2];data_byte[7] <= reg_data_byte[7][2];end//----reg_data_byte----------------------always@(posedge clk or negedge rst_n)beginif(!rst_n)beginSTART <= 3'd0;reg_data_byte[0] <= 3'd0; reg_data_byte[1] <= 3'd0;reg_data_byte[2] <= 3'd0;reg_data_byte[3] <= 3'd0;reg_data_byte[4] <= 3'd0;reg_data_byte[5] <= 3'd0;reg_data_byte[6] <= 3'd0;reg_data_byte[7] <= 3'd0;STOP <= 3'd0;end else if(baud_clk)begincase(baud_cnt) //0:initial baud_cnt=0 --> after sending data, rs232_tx always be 0; 0: beginSTART <= 3'd0;reg_data_byte[0] <= 3'd0; reg_data_byte[1] <= 3'd0;reg_data_byte[2] <= 3'd0;reg_data_byte[3] <= 3'd0;reg_data_byte[4] <= 3'd0;reg_data_byte[5] <= 3'd0;reg_data_byte[6] <= 3'd0;reg_data_byte[7] <= 3'd0;STOP <= 3'd0;end6,7,8,9,10,11: START <= START + rs232_rx_reg2;22,23,24,25,26,27: reg_data_byte[0] <= reg_data_byte[0] + rs232_rx_reg2;38,39,40,41,42,43: reg_data_byte[1] <= reg_data_byte[1] + rs232_rx_reg2;54,55,56,57,58,59: reg_data_byte[2] <= reg_data_byte[2] + rs232_rx_reg2;70,71,72,73,74,75: reg_data_byte[3] <= reg_data_byte[3] + rs232_rx_reg2;86,87,88,89,90,91: reg_data_byte[4] <= reg_data_byte[4] + rs232_rx_reg2;102,103,104,105,106,107: reg_data_byte[5] <= reg_data_byte[5] + rs232_rx_reg2;118,119,120,121,122,123: reg_data_byte[6] <= reg_data_byte[6] + rs232_rx_reg2;130,131,132,133,134,135: reg_data_byte[7] <= reg_data_byte[7] + rs232_rx_reg2;148,149,150,151,152,153: STOP <= STOP + rs232_rx_reg2;default beginSTART <= START;reg_data_byte[0] <= reg_data_byte[0]; reg_data_byte[1] <= reg_data_byte[1];reg_data_byte[2] <= reg_data_byte[2];reg_data_byte[3] <= reg_data_byte[3];reg_data_byte[4] <= reg_data_byte[4];reg_data_byte[5] <= reg_data_byte[5];reg_data_byte[6] <= reg_data_byte[6];reg_data_byte[7] <= reg_data_byte[7];STOP <= STOP; endendcaseendend endmodule
//------------------------------------------------
//----testbench-----------------------------------
`timescale 1ns/1ns
`define clk_period 20module uart_rx_r0_tb;reg clk;reg rst_n;reg [7:0] data_byte_tx;wire rx_done;reg send_en;reg [2:0] baud_set;wire [7:0] data_byte_rx;wire rs232_rx;wire tx_done;//wire uart_state; wire led;uart_rx_r0 uut_rx(.clk(clk),.rst_n(rst_n),.rs232_rx(rs232_rx),.baud_set(baud_set),.rx_done(rx_done),.data_byte(data_byte_rx));uart_tx_r0 uut_tx(.clk(clk),.rst_n(rst_n),.send_en(send_en),.baud_set(baud_set),.tx_done(tx_done),.data_byte(data_byte_tx),.uart_state(led),.rs232_tx(rs232_rx));initial beginclk = 1;rst_n = 0;send_en = 0;baud_set = 3'd4;#(`clk_period*20+1);rst_n = 1;#(`clk_period*50);data_byte_tx = 8'haa;//8'b1010_1010send_en = 1;#`clk_period;send_en = 0;@(posedge tx_done)#(`clk_period*5000);data_byte_tx = 8'h55;//0101_0101send_en = 1;#`clk_period;send_en = 0;@(posedge tx_done)#(`clk_period*5000);$stop;endalways begin #(`clk_period/2) clk = ~clk;endendmodule
3. Modelsim仿真
4. FPGA板级验证
- 串口助手发送数据,ISSP软件实时接收数据。
[参考资料] FPGA系统设计与验证实战指南
【注】:个人学习笔记,如有错误,望不吝赐教,这厢有礼了~~~
FPGA学习笔记_UART串口协议_串口接收端设计相关推荐
- (实验50)单片机,STM32F4学习笔记,代码讲解【串口IAP实验】【正点原子】【原创】
文章目录 ❤2023重新理解记录 其它文章链接,独家吐血整理 实验现象 主程序 IAP初始化程序 代码讲解 文章目录 ❤2023重新理解记录 其它文章链接,独家吐血整理 实验现象 主程序 IAP初始化 ...
- (实验4)单片机,STM32F4学习笔记,代码讲解【串口实验】【正点原子】【原创】
文章目录 其它文章链接,独家吐血整理 实验现象 主程序 串口中断程序 代码讲解 其它文章链接,独家吐血整理 (实验3)单片机,STM32F4学习笔记,代码讲解[按键输入实验][正点原子][原创] (实 ...
- 小梅哥FPGA学习笔记
小梅哥FPGA学习笔记 一.38译码器 功能: 译码器其任一时刻的稳态输出,仅仅与该时刻的输入变量的取值有关,它是一种多输入多输出的组合逻辑电路,负责将二进制代码翻译为特定的对象(如逻辑电平等).38 ...
- FPGA学习笔记(八)同步/异步信号的打拍分析处理及亚稳态分析
系列文章目录 一.FPGA学习笔记(一)入门背景.软件及时钟约束 二.FPGA学习笔记(二)Verilog语法初步学习(语法篇1) 三.FPGA学习笔记(三) 流水灯入门FPGA设计流程 四.FPGA ...
- FPGA 学习笔记:Vivado 2020.2 MicroBlaze MIG 测试 DDR3 篇尾
FPGA 学习笔记:Vivado 2020.2 MicroBlaze MIG 测试 DDR3 篇一 FPGA 学习笔记:Vivado 2020.2 MicroBlaze MIG 测试 DDR3 篇二 ...
- FPGA 学习笔记:Vivado 2018.2 MicroBlaze Uartlite 配置
前言 Vivado 版本: Vivado 2018.2 + Vivado HLS 2018.2, Vivado HLS 2018.2 用于 SDK 开发,C语言开发 创建基于MicroBlaze的 [ ...
- FPGA学习笔记(八):ASK调制解调的仿真
笔记八是ASK调制解调的仿真实现. ASK调制解调的实现原理:首先使用MATLAB产生存储基带波形的coe文件,再让ROM读取coe文件输出基带波形,然后DDS产生正弦波信号作为载波信号,接下来使用乘 ...
- FPGA学习笔记之Altera FPGA使用JIC文件配置固化教程
FPGA学习笔记之Altera FPGA使用JIC文件配置固化教程 很多做过单片机的朋友都知 道,我们在对MCU烧写完程序固件后,那么该程序固件就存储在了该MCU内部.即使MCU断电了再重新上电,程序 ...
- IOS之学习笔记十五(协议和委托的使用)
1.协议和委托的使用 1).协议可以看下我的这篇博客 IOS之学习笔记十四(协议的定义和实现) https://blog.csdn.net/u011068702/article/details/809 ...
最新文章
- Android studio 代码字体模糊的处理方法
- 一个button导致的慘案
- java聊天室 博客_java网络聊天室
- IOS 总结:NSArray,NSSet,NSDictionary
- python plot方法的使用_【python】matplotlib.pyplot入门
- 关于完美拖拽的问题三
- OpenStack精华问答 | OpenStack的网络类型有哪些?
- linux5 yum安装,(5)Linux_软件管理_yum安装本地软件
- 脚本中调用别的脚本,如何得到执行结果?
- Navicat for mysql破解版安装步骤
- NOI / 1.3编程基础之算术表达式与顺序执行——12:计算球的体积
- 2.12美团点评技术
- UC伯克利教授Stuart Russell人工智能基础概念与34个误区 (公号回复“AI基础概念”可下载PDF资料)
- 洛谷千题详解 | P1010 [NOIP1998 普及组] 幂次方【C++、Java、Python、Pascal语言】
- 黄健翔:观看欧冠决赛的建议!
- Linux FTP用户设置与宽带限制
- vue 高德地图 不同区域显示不同颜色_高德地图车机版4.0解析:看不见的升级才是重点...
- 牛逼,Python3竟然内置找茬神器!一起来找茬吧!
- cnpm : 无法加载文件 C:\Users\***\AppData\Roaming\npm\cnpm.ps1,因为在此系统上禁止运行脚本
- 华为mate10用的android版本,硬件有区别!华为Mate10哪个版本性价比更高
热门文章
- ios开发聊天气泡实现
- 解决Solaris应用程序开发内存泄漏问题
- 说说tushare pro积分规则或积分获取的那些坑!
- 收音机设计与制作漫谈(转)
- linux qt地图开发教程,基于QT的电子地图的设计与实现
- 输出任意边长的菱形————C语言实践应用(1)(完整源码)
- RealFlow在线教程翻译(2)——Foam with SPH Fluids(基于平滑粒子流体动力学算法(SPH)的流体泡沫)
- python每个数都可由集合中的某两个数相加而得
- Minecraft 1.18.1、1.18.2模组开发 05.发射器+投掷物
- 【51单片机】计时器/计数器中断