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. 【Linux命令】--(1)文件文件夹操作命令15条

    文件文件夹操作命令++++++++++++++++++++++++++++++++++++++++ 列出进入显示文件夹     ls cd pwd  创建移动删除文件     mkdir rm rmd ...

  2. TensorFlow 官方文档中文版

    http://wiki.jikexueyuan.com/list/deep-learning/ TensorFlow 官方文档中文版 你正在阅读的项目可能会比 Android 系统更加深远地影响着世界 ...

  3. 1732 Fibonacci数列 2

    1732 Fibonacci数列 2  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题解       题目描述 Description 在“1250 F ...

  4. 01-S3C2440学习入门概念+环境搭建【转】

    本文转载自:http://blog.csdn.net/fengyuwuzu0519/article/details/54754812 一.心得: 这两年学过很多东西,有点杂,总感觉不够踏实,于是准备写 ...

  5. CodeForces - 557D Vitaly and Cycle(二分图)

    Vitaly and Cycle time limit per test 1 second memory limit per test 256 megabytes input standard inp ...

  6. 【HDU 4699】 Editor

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=4699 [算法] 维护两个栈,一个栈放光标之前的数,另外一个放光标之后的数 在维护栈的同时求最大前缀 ...

  7. cf578c Weakness and Poorness 三分

    其实三分就是一个求单峰函数的最值的东西,用法比较统一.这个题就是观察发现不美好值是一个单峰函数,然后枚举t进行三分就行了. 题干: 给定一个长度为n的数组ai,求一个实数x,使得序列a1-x,a2-x ...

  8. 懒人学习automake, Makefile.am,configure.ac

    已经存在Makefile.am,如何生成Makefile? 步骤: [root@localhost hello]# autoscan .///在当前文件夹中搜索 [root@localhost hel ...

  9. php 时间戳和时间的转换

    PHP的时间戳与具体时间转化 三个内置函数: time() //获取UNIX系统时间戳 mktime(hour,minute,second,month,day,year) //将指定时间转化为时间戳 ...

  10. 通过类库ChineseChar实现将汉字转化为拼音

    //封装dllusing Microsoft.International.Converters.PinYinConverter;using System.Text;namespace Utils{ p ...