6635|9

109

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

FPGA实现UART收发器 [复制链接]


  1. module UART ( rst,clk50M,send_en,rev_en,TXD,TXD_data,RXD,RXD_data);
  2. input rst,clk50M,RXD,send_en,rev_en;
  3. input [7:0] TXD_data;
  4. output TXD;
  5. reg TXD;
  6. reg [7:0] TXD_cnt;

  7. output [7:0] RXD_data;
  8. reg [7:0] RXD_data;
  9. reg [7:0] RXD_cnt;

  10. parameter baud=9600;        //any baud is OK;
  11. //frediv = fclk/(16*baud)
  12. //e.g. fclk=50M,9600 baud,frediv=326
  13. /*parity check
  14. even parity:1'b0 XOR d[0] ~ d[7];
  15. odd parity :1'b1 XOR d[0] ~ d[7];
  16. */
  17. reg [11:0] fre_cnt;
  18. reg clk_baud;
  19. always@(negedge rst or posedge clk50M)
  20.         if(!rst)
  21.                 fre_cnt<=1'b0;
  22.         else
  23.                 if(clk50M)                                               
  24.                         if(fre_cnt==(50000000/(16*baud)))
  25.                                 fre_cnt<=1'b0;
  26.                         else
  27.                                 begin
  28.                                 fre_cnt<=fre_cnt+1'b1;
  29.                                 if(fre_cnt<=(50000000/(16*baud))/2)
  30.                                         clk_baud<=1'b1;
  31.                                 else
  32.                                         clk_baud<=1'b0;
  33.                                 end
  34.                                
  35. always@(negedge rst or posedge clk_baud)
  36.         if(!rst)
  37.                 begin
  38.                 TXD_cnt<=1'd0;
  39.                 TXD<=1'b1;
  40.                 end
  41.         else
  42.                 if(clk_baud)
  43.                         begin
  44.                         if(send_en)
  45.                                 case(TXD_cnt)
  46.                                         8'd0        :        begin
  47.                                                                 TXD<=1'b0;
  48.                                                                 TXD_cnt<=TXD_cnt+8'd1;
  49.                                                                 end
  50.                                         8'd16        :         begin
  51.                                                                 TXD<=TXD_data[0];
  52.                                                                 TXD_cnt<=TXD_cnt+8'd1;
  53.                                                                 end
  54.                                         8'd32        :         begin
  55.                                                                 TXD<=TXD_data[1];
  56.                                                                 TXD_cnt<=TXD_cnt+8'd1;
  57.                                                                 end                       
  58.                                         8'd48        :         begin
  59.                                                                 TXD<=TXD_data[2];
  60.                                                                 TXD_cnt<=TXD_cnt+8'd1;
  61.                                                                 end
  62.                                         8'd64        :         begin
  63.                                                                 TXD<=TXD_data[3];
  64.                                                                 TXD_cnt<=TXD_cnt+8'd1;
  65.                                                                 end
  66.                                         8'd80        :         begin
  67.                                                                 TXD<=TXD_data[4];
  68.                                                                 TXD_cnt<=TXD_cnt+8'd1;
  69.                                                                 end
  70.                                         8'd96        :         begin
  71.                                                                 TXD<=TXD_data[5];
  72.                                                                 TXD_cnt<=TXD_cnt+8'd1;
  73.                                                                 end
  74.                                         8'd112        :         begin
  75.                                                                 TXD<=TXD_data[6];
  76.                                                                 TXD_cnt<=TXD_cnt+8'd1;
  77.                                                                 end
  78.                                         8'd128        :         begin
  79.                                                                 TXD<=TXD_data[7];
  80.                                                                 TXD_cnt<=TXD_cnt+8'd1;
  81.                                                                 end
  82.                                         8'd144        :         begin
  83.                                                                 TXD<=1'b1;
  84.                                                                 TXD_cnt<=TXD_cnt+8'd1;
  85.                                                                 end
  86.                                         8'd160        :        TXD_cnt<=8'd0;
  87.                                         default        :        TXD_cnt<=TXD_cnt+8'd1;
  88.                                 endcase
  89.                         else
  90.                                 begin
  91.                                 TXD<=1'b1;
  92.                                 TXD_cnt<=8'd0;
  93.                                 end
  94.                 end
  95.                                
  96.        
  97. always@(negedge rst or posedge clk_baud)
  98.         if(!rst)               
  99.                 RXD_cnt<=1'd0;               
  100.         else
  101.                 if(clk_baud)
  102.                         begin
  103.                         if(rev_en)                       
  104.                                 case(RXD_cnt)
  105.                                         8'd0        :        if(!RXD)
  106.                                                                         RXD_cnt<=RXD_cnt+8'd1;
  107.                                                                 else
  108.                                                                         RXD_cnt<=8'd0;                                                       
  109.                                         8'd16        :         begin
  110.                                                                 RXD_data[0]<=RXD;
  111.                                                                 RXD_cnt<=RXD_cnt+8'd1;
  112.                                                                 end
  113.                                         8'd32        :         begin
  114.                                                                 RXD_data[1]<=RXD;
  115.                                                                 RXD_cnt<=RXD_cnt+8'd1;
  116.                                                                 end                       
  117.                                         8'd48        :         begin
  118.                                                                 RXD_data[2]<=RXD;
  119.                                                                 RXD_cnt<=RXD_cnt+8'd1;
  120.                                                                 end
  121.                                         8'd64        :         begin
  122.                                                                 RXD_data[3]<=RXD;
  123.                                                                 RXD_cnt<=RXD_cnt+8'd1;
  124.                                                                 end
  125.                                         8'd80        :         begin
  126.                                                                 RXD_data[4]<=RXD;
  127.                                                                 RXD_cnt<=RXD_cnt+8'd1;
  128.                                                                 end
  129.                                         8'd96        :         begin
  130.                                                                 RXD_data[5]<=RXD;
  131.                                                                 RXD_cnt<=RXD_cnt+8'd1;
  132.                                                                 end
  133.                                         8'd112        :         begin
  134.                                                                 RXD_data[6]<=RXD;
  135.                                                                 RXD_cnt<=RXD_cnt+8'd1;
  136.                                                                 end
  137.                                         8'd128        :         begin
  138.                                                                 RXD_data[7]<=RXD;
  139.                                                                 RXD_cnt<=RXD_cnt+8'd1;
  140.                                                                 end
  141.                                         8'd144        :         if(RXD)
  142.                                                                         RXD_cnt<=RXD_cnt+8'd1;
  143.                                                                 else
  144.                                                                         RXD_cnt<=8'd144;
  145.                                         8'd160        :        RXD_cnt<=8'd0;
  146.                                         default        :        RXD_cnt<=RXD_cnt+8'd1;
  147.                                 endcase
  148.                         else
  149.                                 RXD_cnt<=8'd0;
  150.                 end
  151.                                
  152. endmodule
复制代码
此帖出自FPGA/CPLD论坛

最新回复

这段代码不稳定。 由于采用了内部生成的信号作为UART的时钟,会使时钟产生很多毛刺。同时,由于生成的时钟信号需要走局部走线,会产生hold-time violation. 系统在硬件上会非常不稳定。 正确的写法是把生成的时钟信号作为enable. 如果有空可以参考一下opencores.org上的代码。   详情 回复 发表于 2015-7-28 16:05
点赞 关注
 

回复
举报

6

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
楼主,如果你能在写代码的时候,写上解释语句,我想会更好的。
此帖出自FPGA/CPLD论坛
 
 

回复

16

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
代码虽然不错  不过没有注释 不容易看懂
此帖出自FPGA/CPLD论坛
 
 
 

回复

26

帖子

0

TA的资源

一粒金砂(初级)

4
 
太简单了,没一点抗干扰能力
此帖出自FPGA/CPLD论坛
 
 
 

回复

55

帖子

0

TA的资源

一粒金砂(初级)

5
 
嗯,不错~
此帖出自FPGA/CPLD论坛
个人签名搏击长空,遨游知识的海洋!
 
 
 

回复

15

帖子

0

TA的资源

一粒金砂(初级)

6
 
没有注释叫新手怎么看呀,伤不起呀
此帖出自FPGA/CPLD论坛
 
 
 

回复

521

帖子

0

TA的资源

一粒金砂(初级)

7
 
FPGA实现UART收发器
此帖出自FPGA/CPLD论坛
 
 
 

回复

33

帖子

0

TA的资源

一粒金砂(初级)

8
 
挺好
此帖出自FPGA/CPLD论坛
 
 
 

回复

16

帖子

1

TA的资源

一粒金砂(中级)

9
 
学习一下
此帖出自FPGA/CPLD论坛
 
 
 

回复

130

帖子

0

TA的资源

纯净的硅(高级)

10
 
这段代码不稳定。 由于采用了内部生成的信号作为UART的时钟,会使时钟产生很多毛刺。同时,由于生成的时钟信号需要走局部走线,会产生hold-time violation. 系统在硬件上会非常不稳定。 正确的写法是把生成的时钟信号作为enable. 如果有空可以参考一下opencores.org上的代码。
此帖出自FPGA/CPLD论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表