Uart串口收发回环验证

  • 接受模块
  • 发送模块
  • 波特率设置模块
  • 顶层模块
  • TB
  • Modelsim仿真结果
  • 板级验证
  • 总结

本次所做的项目比较复杂(对我本人来讲),设计一个Uart IP核,在其基础,封装axi接口,使其成为面向AXI口的IP,再例化个microblaze作为主机,使microblaze与Uart之间通过AXI总线进行通信。具体模块图如下,包含主机microblaze,主接口模块,从接口模块,从机Uart。


本文首先介绍Uart基本模块。该顶层模块包含接受模块、发送模块、发送波特率设置模块、接受波特率设置模块。为了方便验证,我们将接受模块与发送模块连接,采用回环的形式。

接受模块

`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2019/05/24 16:58:41
// Design Name:
// Module Name: uart_rx
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module uart_rx(clk,rst_n,Rs232_rx,bps_clk,rx_data,rx_int,bps_start);input clk;input rst_n;input bps_clk;input Rs232_rx;output [7:0] rx_data;output reg rx_int;output reg bps_start;reg Rs232_rx0,Rs232_rx1,Rs232_rx2,Rs232_rx3;wire neg_edge;reg [3:0] num;reg [7:0] rx_data_t1; reg [7:0] rx_data_t2;always@(posedge clk or negedge rst_n)if(!rst_n) begin Rs232_rx0 <= 1'b1;Rs232_rx1 <= 1'b1;Rs232_rx2 <= 1'b1;Rs232_rx3 <= 1'b1;endelse beginRs232_rx0 <= Rs232_rx;Rs232_rx1 <= Rs232_rx0;Rs232_rx2 <= Rs232_rx1;Rs232_rx3 <= Rs232_rx2;    endassign neg_edge = Rs232_rx3 & Rs232_rx2 & ~Rs232_rx1 & ~Rs232_rx0;always@(posedge clk or negedge rst_n)if(!rst_n) beginbps_start <= 1'b0;rx_int <= 1'b0;endelse if (neg_edge) begin bps_start <= 1'b1;rx_int <= 1'b1;endelse if (num == 4'd10) beginbps_start <= 1'b0;rx_int <= 1'b0;  end always@(posedge clk or negedge rst_n)if(!rst_n) beginrx_data_t1 <= 8'd0; rx_data_t2 <=8'd0;num <= 4'd0;endelse if(rx_int) begin if (bps_clk) begin num <= num+1'b1;case(num)4'd1: rx_data_t1[0] <= Rs232_rx;4'd2: rx_data_t1[1] <= Rs232_rx;4'd3: rx_data_t1[2] <= Rs232_rx;4'd4: rx_data_t1[3] <= Rs232_rx;4'd5: rx_data_t1[4] <= Rs232_rx;4'd6: rx_data_t1[5] <= Rs232_rx;4'd7: rx_data_t1[6] <= Rs232_rx;4'd8: rx_data_t1[7] <= Rs232_rx;default:;endcase endend       else if(num >= 4'd9) begin num <= 4'd0;rx_data_t2 <= rx_data_t1;endassign  rx_data = rx_data_t2;  endmodule

发送模块

`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2019/05/24 15:39:09
// 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(clk,rst_n,tx_int,rx_data,bps_clk,Rs232_tx,bps_start);input clk;input rst_n;input tx_int;input [7:0] rx_data;input bps_clk;output Rs232_tx;output bps_start;reg tx_int0;reg tx_int1;reg tx_int2;wire neg_edge;(* keep = "true" *) reg en;reg [3:0] num;reg bps_start_t;//reg [7:0] rx_data_t;reg Rs232_tx_t;always@(posedge clk or negedge rst_n)if(!rst_n) begin tx_int0 <= 1'b0;tx_int1 <= 1'b0;tx_int2 <= 1'b0;endelse begintx_int0 <= tx_int;tx_int1 <= tx_int0;tx_int2 <= tx_int1;end   assign neg_edge = tx_int2 & ~tx_int1;always@(posedge clk or negedge rst_n)if(!rst_n) begin en <= 1'b0;bps_start_t <= 1'b0;endelse if (neg_edge) beginen <= 1'b1;bps_start_t <= 1'b1;//rx_data_t <= rx_data;end    else if (num == 4'd10) beginen <= 1'b0;bps_start_t <= 1'b0;  endassign bps_start = bps_start_t;always@(posedge clk or negedge rst_n)if(!rst_n) begin Rs232_tx_t <= 1'b1;num <= 12'd0;endelse if (en) begin if (bps_clk) begin case (num) 4'd0: Rs232_tx_t <= 1'b0;4'd1: Rs232_tx_t <= rx_data[0];4'd2: Rs232_tx_t <= rx_data[1];4'd3: Rs232_tx_t <= rx_data[2];4'd4: Rs232_tx_t <= rx_data[3];4'd5: Rs232_tx_t <= rx_data[4];4'd6: Rs232_tx_t <= rx_data[5];4'd7: Rs232_tx_t <= rx_data[6];4'd8: Rs232_tx_t <= rx_data[7];4'd9: Rs232_tx_t <= 1'b1;default: Rs232_tx_t <= 1'b1;endcasenum <= num +1'b1;  end   end        else if(num == 4'd10) beginnum <= 1'b0;       end      assign Rs232_tx = Rs232_tx_t;endmodule

波特率设置模块

`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2019/05/24 15:06:47
// Design Name:
// Module Name: speed_set
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module speed_set(bps_start,clk,rst_n,bps_clk);input bps_start;input clk;input rst_n;output reg bps_clk;(* keep = "true" *) reg [12:0] cnt;`define BPS_NUM 5207`define BPS_NUM_2 2306always@(posedge clk or negedge rst_n)if (!rst_n)cnt <= 13'd0;else if (cnt == `BPS_NUM ||  !bps_start)cnt <= 13'd0;else cnt <= cnt + 1'b1;always@(posedge clk or negedge rst_n)if(!rst_n)bps_clk <= 1'b0;else if (cnt == `BPS_NUM_2)bps_clk <= 1'b1;else bps_clk <= 1'b0;endmodule

顶层模块

`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2019/05/27 10:00:56
// Design Name:
// Module Name: uart_top
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module uart_top(clk_p,clk_n,rst_n,Rx,Tx);input clk_p;input clk_n;input rst_n;input Rx;output Tx;wire clk_50m;wire bps_clk_tx;wire bps_clk_rx;wire bps_start_tx;wire bps_start_rx;wire [7:0] rx_data;wire int;clk_wiz_0 instance_name(// Clock out ports.clk_50m(clk_50m),     // output clk_50m// Status and control signals.resetn(rst_n), // input resetn// Clock in ports.clk_in1_p(clk_p),    // input clk_in1_p.clk_in1_n(clk_n));    // input clk_in1_nspeed_set speed_tx(.bps_start(bps_start_tx),.clk(clk_50m),.rst_n(rst_n),.bps_clk(bps_clk_tx));        uart_tx uart_tx(.clk(clk_50m),.rst_n(rst_n),.tx_int(int),.rx_data(rx_data),.bps_clk(bps_clk_tx),.Rs232_tx(Tx),.bps_start(bps_start_tx));speed_set speed_rx(.bps_start(bps_start_rx),.clk(clk_50m),.rst_n(rst_n),.bps_clk(bps_clk_rx));uart_rx uart_rx(.clk(clk_50m),.rst_n(rst_n),.Rs232_rx(Rx),.bps_clk(bps_clk_rx),.rx_data(rx_data),.rx_int(int),.bps_start(bps_start_rx));
endmodule

TB

`timescale 1ns / 1ps
`define clock_period 20
//
// Company:
// Engineer:
//
// Create Date: 2019/05/27 10:38:22
// Design Name:
// Module Name: uart_tb
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module Uart_tb;reg clk_p;reg clk_n;reg rst_n;reg Rx;wire Tx;uart_top uart_top(.clk_p(clk_p),.clk_n(clk_n),.rst_n(rst_n),.Rx(Rx),.Tx(Tx));initial clk_p = 0;always #2.5 begin clk_p = ~clk_p;clk_n = ~clk_p;endinitial beginRx = 1'b1; rst_n = 1'b0;#(`clock_period*20);rst_n = 1'b1;#(`clock_period*52080);//起始位Rx = 1'b0;       #(`clock_period*5208);//数据位Rx = 1'b1;  #(`clock_period*5208);Rx = 1'b0; #(`clock_period*5208);Rx = 1'b0; #(`clock_period*5208);Rx = 1'b0; #(`clock_period*5208);Rx = 1'b1; #(`clock_period*5208);Rx = 1'b0; #(`clock_period*5208);Rx = 1'b0; #(`clock_period*5208);Rx = 1'b0; #(`clock_period*5208);//停止位Rx = 1'b1; #(`clock_period*5208); Rx = 1'b1; #(`clock_period*52080); endendmodule

Modelsim仿真结果

板级验证

总结

本项目Uart设计没有什么难度,基本原理在看完Uart之后spe之后基本了解,再加上之前有点底子,在代码表写上很快完成。但由于Vivado工具使用不熟练,导致花费大量时间,尤其在debug调试之后生成ILA核,抓取的波形不知道怎么看,自己摸索始终不会,最终还是在 老同志的帮助下知道了怎么回事,一方面感谢,另一发方面感概其其奇妙之后,感觉在数字芯片这么难之下下,我们工程师(妄称)还是要多多交流,这样才能共同进步。终极学习法费曼学习法不是说了吗,学习最快的途径是教会一个外行人,你教别人的同时自己也在快速成长。另外自身而言,实在琢磨不出在,还是问问别人,又是你半天搞不出来,一问就回了,提高效率不是。
扯哪去了,回归正题。在前期写好代码之后,兴致勃勃地仿真还通过了,感觉没啥问题,直接上板子烧入,之后崩了,没有结果。前期以为串口工具有问题,想不到还真有问题,板子上USB口接错了,COM口出错,小白尽是犯这种低级错误啊。改完之后重新烧入,还是不行,心态有点炸。实在没办法请教了大神,让我用debug来找出代码那不对,刚开始我始终不以为意,认为仿真通过我写的代码肯定没问题,肯定是其他硬件问题。再加上我debug不会用,浪费了大量时间。在慢慢琢磨与请教之后,发现了问题(前方高能):
1.我在一个always进程中对一个变量赋值之前,没有对其进行复位(TX模块的bps_start_t),导致仿真出现红线未知态。不过这不是主要问题
2.也是tx模块中我竟然多num信号在两个进程中同时对其赋值,明显不过的代码错误,但是综合尽然通过了,什么鬼
总结:
在那个alway进程中间对所有变量赋值之前,现在Rst中对所有进行复位
不要感觉没有错误仿真通过就感觉代码没问题,万事大吉EDA也不是万能的,错误看完的看看警告。
对变量进行暂存再赋值是将reg型变量变为wire型。如果其他进程用到了就不需要转变,只是偶尔输出时需要转变。

Uart串口收发回环验证相关推荐

  1. MTK:UART串口收发数据

    MTK之UART串口收发数据 转:https://blog.csdn.net/ivy_reny/article/details/51192110 寄存器 UARTn_RBR: Rx Buffer Re ...

  2. c8051f020C语言程序,C8051F020编程UART串口收发数据

    C8051F020编程UART串口收发数据 我编了一个 老是编译不过去 求高手改正 我用的是UART0端口 方式2 程序如下 //>>UART0串口编程--向PC发送和接受字符串<& ...

  3. 【CubeIDE】STM32 HAL库史上最详细教程(一):UART串口收发

    博主能力有限,有错误望大佬指出 0x00 文章内容: UART阻塞方式收发 UART中断方式收发 UART中断回调函数 UART DMA方式收发 printf()函数串口重定向 0x01 UART阻塞 ...

  4. MTK之UART串口收发数据

    寄存器 UARTn_RBR: Rx Buffer Register,通过读取该寄存器接收数据.要求LCR[7]=0.  UARTn_THR: Tx Holding Register,数据先写入该寄存器 ...

  5. 【程序】Altera FPGA NIOS实现Scatter-Gather DMA(SGDMA)收发回环测试,描述符和缓冲区全部放在同一块SDRAM里面

    Quartus II 13.0工程下载地址:https://pan.baidu.com/s/1qjkqhd7-1IKNWZUaiZVW7Q(提取码:64wu) [开发板] 开发板型号:小梅哥AC620 ...

  6. UART串口通信(回环测试)

    一 UART串口通信简介 UART(Universal Asynchronous Receiver-Transmitter)是采用异步串行通信方式的通用异步收发传输器,在发送数据时将并行数据转换为串行 ...

  7. 基于FPGA实现uart串口模块(Verilog)--------发送模块及整合

    基于FPGA实现uart串口模块(Verilog)--------发送模块及整合 当接收模块接收到数据后,需要重新发送形成回环验证模块正确性.思路和结束模块有一点点的小差异.接收模块最终输出的是一个并 ...

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

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

  9. 基于FPGA实现uart串口模块(Verilog)--------接收模块及思路总结

    基于FPGA实现uart串口模块(Verilog)--------接收模块及思路总结 uart通信协议简单理解为串转并和并转串的两个模块.同时必须保证数据的正确性.且输入输出端为串行. 此次实现uar ...

最新文章

  1. 由于市场判断失误 希捷降低收入预期
  2. freebsd mysql删_FreeBSD 下 mysql 的相关问题
  3. android中extends 和implements的区别
  4. go hello world第一个程序
  5. 学习在网页中应用大图片背景的20个精美案例
  6. 模块简介/模块的导入/模块的查找顺序/绝对导入和相对导入/软件开发目录规范...
  7. 866. 试除法判定质数
  8. php str_replice_详解PHP字符串替换str_replace()函数四种用法
  9. Python编程 | 新手必会的 9 个 Python 技巧
  10. Python中的输入输出(IO)
  11. asp.net社区户籍档案管理系统
  12. VISA/MasterCard/AE/DC/JCB卡号结构
  13. 绘画教程:动漫人体肌肉的详细画法
  14. cass坡度土方计算案例_CASS土方量计算总结
  15. 做计算机用英语怎么读,计算机英语怎么读
  16. 【Cesium】添加polygon边界线
  17. 防范于未“燃”|涂鸦智慧社区推出“黑科技”,电瓶车禁入电梯智慧方案
  18. 2020 年最具潜力 44 个顶级开源项目,涵盖 11 类 AI 学习框架、平台(值得收藏)...
  19. Android 获取微信ua,微信小程序实现获取用户高清头像
  20. 羊了怎么居家办公?免费不限速的远程控制软件RayLink一解燃眉之急!!

热门文章

  1. 完美国际最新服务器,完美国际2:新服“永恒”明日开启,新老朋友踏实安家...
  2. flutter中使用android原生视图
  3. 聊一聊Mysql中的字符串拼接函数
  4. Python signal 信号处理模块
  5. petalinux在zynq平台移植和双网口实现
  6. Linex新手常用命令
  7. 请你估算一下,在春节前倒数第三天,首都国际机场一天的人流量。
  8. pytorch训练时显存溢出
  9. 大一经历 不全是 寥寥草草应付申报单项奖
  10. 【调剂】深圳大学大湾区国际创新学院2023年人工智能专业研究生预调剂信息