2018年7月24日

uart 接收 部分测试成功,多谢开源骚客 邓堪文老师 ,想学的同学可以微信公众号搜索开源骚客

好啦!言归正传。

1.先附上老师的时序图,自己有点懒不想画,rx_t、rx_tt、rx_ttt分别对应源码中的rx_r1、rx_r2、rx_r2。

认真理解时序图,代码具体怎么实现就好理解了。

2.需要说明的是baud_cnt这个计数器,他是波特率的计数器,计数原理了解这个公式

3.剩下的就自己结合一下源码

 `define SIM

 module  uart_rx(
//system signale
input sclk ,
input s_rst_n ,
//uart interface
input rs232_rx ,
//other
output reg [:] rx_data ,
output reg po_flag ); //-----------------------------------------------------------------\
//***********Difine Parameter and Internal signals*****************
//-----------------------------------------------------------------/
`ifndef SIM
localparam BAUD_END = ;
`else
localparam BAUD_END = ;
`endif
localparam BAUD_M = BAUD_END/- ;
localparam BIT_END = ; reg rx_r1 ;
reg rx_r2 ;
reg rx_r3 ;
reg rx_flag ;
reg [:] baud_cnt ;
reg bit_flag ;
reg [:] bit_cnt ; //==================================================================\
//****************Main Code *********************************
//==================================================================/ //捕获起始位下降沿
assign rx_neg = ~rx_r2 & rx_r3; always @(posedge sclk ) begin
rx_r1 <= rs232_rx;
rx_r2 <= rx_r1;
rx_r3 <= rx_r2;
end //接收数据标志
always @(posedge sclk or negedge s_rst_n) begin
if(s_rst_n == 'b0)
rx_flag <= 'b0;
else if(rx_neg == 'b1)
rx_flag <= 'b1;
else if(bit_cnt == 'd0 && baud_cnt == BAUD_END)
rx_flag <= 'b0;
end //波特率生成
always @(posedge sclk or negedge s_rst_n ) begin
if(s_rst_n == 'b0)
baud_cnt <= 'd0;
else if(baud_cnt == BAUD_END)
baud_cnt <= 'd0;
else if(rx_flag == 'b1)
baud_cnt <= baud_cnt + 'b1;
else
baud_cnt <= 'd0;
end //位接收有效
always @(posedge sclk or negedge s_rst_n) begin
if(s_rst_n == 'b0)
bit_flag <= 'b0;
else if (baud_cnt == BAUD_M)
bit_flag <= 'b1;
else
bit_flag <= 'b0;
end //位计数
always @(posedge sclk or negedge s_rst_n) begin
if(s_rst_n == 'b0)
bit_cnt <= 'd0;
else if(bit_flag == 'b1 && bit_cnt == BIT_END )
bit_cnt <= 'd0;
else if(bit_flag == 'b1)
bit_cnt <= bit_cnt + 'b1; end //串转并
always @(posedge sclk or s_rst_n) begin
if(s_rst_n == 'b0)
rx_data <= 'd0;
else if (bit_flag == 'b1 && bit_cnt >= 4'd1)
rx_data <= {rx_r2, rx_data[:]};
end
//一位接收完成
always @(posedge sclk or s_rst_n) begin
if(s_rst_n == 'b0)
po_flag <= 'b0;
else if(bit_cnt == BIT_END && bit_flag == 'b1)
po_flag <= 'b1;
else
po_flag <= 'b0;
end endmodule

4.源码这儿需要理解一下 `ifndef ,`else,`endif。这个是预编译处理,详情可以看这位大佬

https://blog.csdn.net/hision_fpgaer/article/details/50909653

5.测试文件,这里需要理解tast使用,以及外部数据文件的的用法(第26行)以及将文件里的数据如何存入二维数组中,tx_data文件就是一般的文本文件,这里设计的技巧太多,可以自己去查询一下。

 `timescale            1ns/1ns
module tb_uart_rx; reg sclk;
reg s_rst_n;
reg rs232_tx; wire po_flag;
wire [:] rx_data; reg [:] mem_a[:]; initial begin
sclk = ;
s_rst_n = ;
rs232_tx = ;
#
s_rst_n = ;
#
tx_tyte();
end always # sclk = ~sclk; initial $readmemh("./tx_data.txt",mem_a); task tx_tyte();
integer i ;
for(i = ;i < ; i = i +) begin
tx_bit(mem_a[i]);
end endtask task tx_bit(
input [:] data
);
integer i;
for(i = ; i < ; i = i+)begin
case(i)
: rs232_tx <= 'b0;
: rs232_tx <= data[];
: rs232_tx <= data[];
: rs232_tx <= data[];
: rs232_tx <= data[];
: rs232_tx <= data[];
: rs232_tx <= data[];
: rs232_tx <= data[];
: rs232_tx <= data[];
: rs232_tx <= 'b1;
endcase
#;
end
endtask uart_rx uart_rx_inst(
//system signale
.sclk (sclk ),
.s_rst_n (s_rst_n ),
//uart interface
.rs232_rx (rs232_tx ),
//other
.rx_data (rx_data ),
.po_flag (po_flag ) ); endmodule

总结一些自己,大一下学期期末左右接触到fpga,自己就爱好电子设计,大一一来就学了51单片机,下学期看着自己同学都报班32,学的都很好,而自己呢还在玩51,弄3D打印机,那个时候挺迷的。

后来不小心看到了fpga,自己仔细去查了,也与32做了比较,斟酌了很久,最后还是下决心学fpga,但是那个我是什么处境呢,同级的一起玩的32都会做很多东西了,自己有小小羞耻感,关键是学校没有人学fpga或者说没有人学的可以的,如果要学的话只能孤军奋战。

后来还是下决心买了板子,自学了一段时间,刚好暑假国赛,我也参加了,打击很大啊,最后还用51做,太丢人了。国赛完,我就自己瞎学fpga,一直因为对fpga的真正的喜爱,以及他那强大而又神秘能力支撑着我学到现在。

刚开始都是看着大佬们的博客一路学习过来,这学期终于翻身了开始自己写博客了,虽然技术含量有点低,哈哈哈,但是还是很开心。到现在差不多学fpga一年了,说实话fpga也让我害怕,不光是她太难驾驭还有的是没啥成就,看其他人啪啪啪的一下子做一堆东西,而自己控制个舵机都吃力。

现在这个暑假,马上又要大三了,趁着时间很多,好好重头在干一次,或许注定是孤独的,我爱你fpga,希望你也爱我,啦啦啦啦啦啦啦!!!!!!!!!!!!!!

完工回去睡觉,fpga等我明天再来宠幸你!

2018年7月26日

uart发送部分以及收发整合,其实是昨天就完事儿了,有事给耽搁了,今天再补来得及。

先说发送部分

1.还是先看时序图,信号都不用解释,直接看图。

2.仔细的同学发现bit_flag这个信号和接收的不一样,这次是baud_cnt波特率计数器记完再触发,而接收的是计数到一半触发,这两种方式作用相同,只是后者稳定一下,自己也可以改。

下面附上接收的源码

  1// `define SIM
module uart_tx(
//system signal
input sclk ,
input s_rst_n ,
//uart interface
output reg rs232_tx ,
//other
input tx_trig ,
input [:] tx_data
); //-----------------------------------------------------------------\
//***********Difine Parameter and Internal signals*****************
//-----------------------------------------------------------------/ `ifndef SIM
localparam BAUD_END = ;
`else
localparam BAUD_END = ;
`endif localparam BAUD_M = BAUD_END/- ;
localparam BIT_END = ; reg [:] tx_data_r ;
reg tx_flag ;
reg [:] baud_cnt ;
reg bit_flag ;
reg [:] bit_cnt ; //==================================================================\
//****************Main Code *********************************
//==================================================================/
//tx_data_r
always @(posedge sclk or negedge s_rst_n) begin
if(s_rst_n == 'b0)
tx_data_r <= 'd0;
else if (tx_trig == 'b1 && tx_flag == 1'b0)
tx_data_r <= tx_data;
end //tx_flag
always @(posedge sclk or negedge s_rst_n) begin
if(s_rst_n == 'b0)
tx_flag <= 'b0;
else if(tx_trig == 'b1 )
tx_flag <= 'b1;
else if (bit_cnt == BIT_END && bit_flag == 'b1)
tx_flag <= 'b0;
end //波特率计数器
always @(posedge sclk or negedge s_rst_n) begin
if(s_rst_n == 'b0)
baud_cnt <= 'd0;
else if (baud_cnt == BAUD_END)
baud_cnt <= 'd0;
else if(tx_flag == 'b1)
baud_cnt <= baud_cnt +'b1;
else
baud_cnt <= 'd0;
end //bit_flag
always @(posedge sclk or negedge s_rst_n) begin
if(s_rst_n == 'b0)
bit_flag <= 'b0;
else if(baud_cnt == BAUD_END)
bit_flag <= 'b1;
else
bit_flag <= 'b0;
end //bit_cnt
always @(posedge sclk or negedge s_rst_n) begin
if(s_rst_n == 'b0)
bit_cnt <= 'd0;
else if(bit_flag == 'b1 && bit_cnt == BIT_END)
bit_cnt <= 'd0;
else if (bit_flag == 'b1)
bit_cnt <= bit_cnt +'b1; end //rs232_tx
always @(posedge sclk or negedge s_rst_n) begin
if(s_rst_n == 'b0)
rs232_tx <= 'b1;
else if(tx_flag == 'b1)
case(bit_cnt)
: rs232_tx <= 'b0;
: rs232_tx <= tx_data_r[];
: rs232_tx <= tx_data_r[];
: rs232_tx <= tx_data_r[];
: rs232_tx <= tx_data_r[];
: rs232_tx <= tx_data_r[];
: rs232_tx <= tx_data_r[];
: rs232_tx <= tx_data_r[];
: rs232_tx <= tx_data_r[];
default:rs232_tx <= 'b1;
endcase
else
rs232_tx <= 'b1;
end endmodule

3.下面附上接收部分的激励源码

 `timescale        1ns/1ns

 module tb_uart_tx;

 reg                sclk;
reg s_rst_n;
reg tx_trig;
reg [:] tx_data;
wire rs232_tx;
//----------------------------------difine system signales-----------------
initial begin
sclk = ;
s_rst_n = ;
#
s_rst_n = ;
end always # sclk = ~sclk; //-----------------------------------------------------------------------
initial begin
tx_data <= 'd0;
tx_trig <= ; #
tx_trig <= 'b1;
tx_data <= 'h55;
#
tx_trig <= 'b0; #
tx_trig <= 'b1;
tx_data <= 'h78;
#
tx_trig <= 'b0; #
tx_trig <= 'b1;
tx_data <= 'h53;
#
tx_trig <= 'b0; end uart_tx uart_tx_inst(
//system signal
.sclk (sclk ),
.s_rst_n (s_rst_n ),
//uart interface
.rs232_tx (rs232_tx ),
//other
.tx_trig (tx_trig ),
.tx_data (tx_data )
); endmodule

最后收发整合前面接收和发送部分都做好的话,这个就很简单了,但是这儿注意一个细节,把模块第一行的   ” `define SIM“给注释掉,这个是仿真用的,不然烧写到板卡不对

 module  uart_top(
//system signals
input sclk ,
input s_rst_n ,
//UART Interface
input rs232_rx ,
output wire rs232_tx
); //-----------------------------------------------------------------\
//***********Difine Parameter and Internal signals*****************
//-----------------------------------------------------------------/
wire [:] rx_data ;
wire tx_trig ;
//==================================================================\
//****************Main Code *********************************
//==================================================================/ uart_rx uart_rx_inst(
//system signale
.sclk (sclk ),
.s_rst_n (s_rst_n ),
//uart interface
.rs232_rx (rs232_rx ),
//other
.rx_data (rx_data ),
.po_flag (tx_trig ) ); uart_tx uart_tx_inst(
//system signal
.sclk (sclk ),
.s_rst_n (s_rst_n ),
//uart interface
.rs232_tx (rs232_tx ),
//other
.tx_trig (tx_trig ),
.tx_data (rx_data )
); endmodule

uart_top

uart学习到此为止了,已完成

基于fpga uart学习笔记的更多相关文章

  1. 串口UART学习笔记(一)

    买了一个开发板学习FPGA,找到的各种东西就记录在这个博客里了,同时也方便把自己不会的问题找到的结果记录一下,都是自己手打,所以可能说的话不那么严谨,不那么精准,看到的人要带着自己的思考去看,记住尽信 ...

  2. .net调用java webservice基于JBOSS服务器 学习笔记(一)

    1.遇到数组类型或List等复杂数据类型是,需要对其进行包装,就是将复杂数据类型放到一个类里面: public class VOCargoJTWS { /** JT列表 */ private List ...

  3. [RAM] FPGA的学习笔记——RAM

    1.RAM——随机存取存储器, 分为SRAM和DRAM. SRAM:存和取得速度快,操作简单.然而,成本高,很难做到很大.FPGA的片内存储器,就是一种SRAM,用来存放程序,以及程序执行过程中,产生 ...

  4. Uart学习笔记

    分享一个蛮好的链接:https://blog.csdn.net/wordwarwordwar/article/details/73662379 今天在看的资料是S家的DW_apb_uart的官方文档. ...

  5. 再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Bluestein算法+分治FFT+FFT的优化+任意模数NTT)

    再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Bluestein算法+分治FFT+FFT的优化+任意模数NTT) 目录 再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Blueste ...

  6. CAS学习笔记五:SpringBoot自动/手动配置方式集成CAS单点登出

    本文目标 基于SpringBoot + Maven 分别使用自动配置与手动配置过滤器方式实现CAS客户端登出及单点登出. 本文基于<CAS学习笔记三:SpringBoot自动/手动配置方式集成C ...

  7. [原创]java WEB学习笔记108:Spring学习---基于配置文件的形式实现AOP

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  8. [原创]java WEB学习笔记85:Hibernate学习之路-- -映射 一对一关系 ,基于主键方式实现

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  9. [原创]java WEB学习笔记49:文件上传基础,基于表单的文件上传,使用fileuoload 组件

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

随机推荐

  1. Office 如何打印A4不干胶标签纸

    1 下载Label Expert这个软件,注意不是第一个Avery Wizard(卖家可能会送你这个软件,但是送的这款软件是简体中文版的,似乎模板不全,所以最好还是自己下,反正我最后是由于找不到对应的 ...

  2. [C++]_[获取Utf8字符串的字符个数和子字符串]

    场景: 1.有时候须要统计utf8字符串的个数,单纯统计字节个数是不行的. 2.有时候也须要获取从某个位置開始的n个连续字符用于显示或计算. static int GetUtf8LetterNumbe ...

  3. CloudEngine 6800基础配置-02_常用命令操作

    查看未提交配置   system-view ftp server enable display configuration candidate   删除未提交的配置 clear configurati ...

  4. Android 驱动 (一) GPIO

    前面的博文对Lichee做了系列分析,事实上就是对在<七年之痒>中所说的,Android BSP具备的一项基本素养-SHELL脚本,所以我们Lichee系列的文章着重分析了SHELL脚本和 ...

  5. 算法题:打印1到最大的n位数

    说明:本文仅供学习交流,转载请标明出处,欢迎转载!        今天看到剑指offer上的第12题,题目例如以下:        输入数字n.按顺序打印出从1到最大的n位十位数. 比方输入3,则打印 ...

  6. JavaScript Patterns 2.7 Avoiding Implied Typecasting

    Dealing with == and === false == 0 or "" == 0 return true. always use the === and !== oper ...

  7. PCB genesis Slot槽转钻孔(不用G85命令)实现方法

    PCB钻Slot槽一般都采用G85命令钻槽孔,而采用G85命令工程CAM无法准确的知道Slot槽钻多少个孔,并不能决定钻槽孔的顺序,因为采用G85命令钻孔密度与钻槽顺序由钻机本身决定的.在这里介绍一种 ...

  8. struts2标签---备忘录

    <s:form action="sloginAction" method="post"> <s:textfield label="用 ...

  9. mysql 数据去重

    update ptop_investrecord set delflag = 1 where cid  = 250 and uid = 92569  and delflag = 0 and progr ...

  10. JavaScript--Array 数组对象

    Array 数组对象 数组对象是一个对象的集合,里边的对象可以是不同类型的.数组的每一个成员对象都有一个“下标”,用来表示它在数组中的位置,是从零开始的 数组定义的方法: 1. 定义了一个空数组: v ...