集成电路技术分享

 找回密码
 我要注册

QQ登录

只需一步,快速开始

搜索
查看: 972|回复: 1

FPGA实现UART收发器

[复制链接]
羽蒙 发表于 2014-7-13 16:51:19 | 显示全部楼层 |阅读模式

module UART ( rst,clk50M,send_en,rev_en,TXD,TXD_data,RXD,RXD_data);
input rst,clk50M,RXD,send_en,rev_en;
input [7:0] TXD_data;
output TXD;
reg TXD;
reg [7:0] TXD_cnt;

output [7:0] RXD_data;
reg [7:0] RXD_data;
reg [7:0] RXD_cnt;

parameter baud=9600;        //any baud is OK;
//frediv = fclk/(16*baud)
//e.g. fclk=50M,9600 baud,frediv=326
/*parity check
even parity:1'b0 XOR d[0] ~ d[7];
odd parity :1'b1 XOR d[0] ~ d[7];
*/
reg [11:0] fre_cnt;
reg clk_baud;
always@(negedge rst or posedge clk50M)
        if(!rst)
                fre_cnt<=1'b0;
        else
                if(clk50M)                                                
                        if(fre_cnt==(50000000/(16*baud)))
                                fre_cnt<=1'b0;
                        else
                                begin
                                fre_cnt<=fre_cnt+1'b1;
                                if(fre_cnt<=(50000000/(16*baud))/2)
                                        clk_baud<=1'b1;
                                else
                                        clk_baud<=1'b0;
                                end
                                
always@(negedge rst or posedge clk_baud)
        if(!rst)
                begin
                TXD_cnt<=1'd0;
                TXD<=1'b1;
                end
        else
                if(clk_baud)
                        begin
                        if(send_en)
                                case(TXD_cnt)
                                        8'd0        :        begin
                                                                TXD<=1'b0;
                                                                TXD_cnt<=TXD_cnt+8'd1;
                                                                end
                                        8'd16        :         begin
                                                                TXD<=TXD_data[0];
                                                                TXD_cnt<=TXD_cnt+8'd1;
                                                                end
                                        8'd32        :         begin
                                                                TXD<=TXD_data[1];
                                                                TXD_cnt<=TXD_cnt+8'd1;
                                                                end                        
                                        8'd48        :         begin
                                                                TXD<=TXD_data[2];
                                                                TXD_cnt<=TXD_cnt+8'd1;
                                                                end
                                        8'd64        :         begin
                                                                TXD<=TXD_data[3];
                                                                TXD_cnt<=TXD_cnt+8'd1;
                                                                end
                                        8'd80        :         begin
                                                                TXD<=TXD_data[4];
                                                                TXD_cnt<=TXD_cnt+8'd1;
                                                                end
                                        8'd96        :         begin
                                                                TXD<=TXD_data[5];
                                                                TXD_cnt<=TXD_cnt+8'd1;
                                                                end
                                        8'd112        :         begin
                                                                TXD<=TXD_data[6];
                                                                TXD_cnt<=TXD_cnt+8'd1;
                                                                end
                                        8'd128        :         begin
                                                                TXD<=TXD_data[7];
                                                                TXD_cnt<=TXD_cnt+8'd1;
                                                                end
                                        8'd144        :         begin
                                                                TXD<=1'b1;
                                                                TXD_cnt<=TXD_cnt+8'd1;
                                                                end
                                        8'd160        :        TXD_cnt<=8'd0;
                                        default        :        TXD_cnt<=TXD_cnt+8'd1;
                                endcase
                        else
                                begin
                                TXD<=1'b1;
                                TXD_cnt<=8'd0;
                                end
                end
                                
        
always@(negedge rst or posedge clk_baud)
        if(!rst)               
                RXD_cnt<=1'd0;               
        else
                if(clk_baud)
                        begin
                        if(rev_en)                        
                                case(RXD_cnt)
                                        8'd0        :        if(!RXD)
                                                                        RXD_cnt<=RXD_cnt+8'd1;
                                                                else
                                                                        RXD_cnt<=8'd0;                                                        
                                        8'd16        :         begin
                                                                RXD_data[0]<=RXD;
                                                                RXD_cnt<=RXD_cnt+8'd1;
                                                                end
                                        8'd32        :         begin
                                                                RXD_data[1]<=RXD;
                                                                RXD_cnt<=RXD_cnt+8'd1;
                                                                end                        
                                        8'd48        :         begin
                                                                RXD_data[2]<=RXD;
                                                                RXD_cnt<=RXD_cnt+8'd1;
                                                                end
                                        8'd64        :         begin
                                                                RXD_data[3]<=RXD;
                                                                RXD_cnt<=RXD_cnt+8'd1;
                                                                end
                                        8'd80        :         begin
                                                                RXD_data[4]<=RXD;
                                                                RXD_cnt<=RXD_cnt+8'd1;
                                                                end
                                        8'd96        :         begin
                                                                RXD_data[5]<=RXD;
                                                                RXD_cnt<=RXD_cnt+8'd1;
                                                                end
                                        8'd112        :         begin
                                                                RXD_data[6]<=RXD;
                                                                RXD_cnt<=RXD_cnt+8'd1;
                                                                end
                                        8'd128        :         begin
                                                                RXD_data[7]<=RXD;
                                                                RXD_cnt<=RXD_cnt+8'd1;
                                                                end
                                        8'd144        :         if(RXD)
                                                                        RXD_cnt<=RXD_cnt+8'd1;
                                                                else
                                                                        RXD_cnt<=8'd144;
                                        8'd160        :        RXD_cnt<=8'd0;
                                        default        :        RXD_cnt<=RXD_cnt+8'd1;
                                endcase
                        else
                                RXD_cnt<=8'd0;
                end
                                
endmodule
zhiweiqiang33 发表于 2014-7-15 17:13:17 | 显示全部楼层
多谢分享 很实用
您需要登录后才可以回帖 登录 | 我要注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

QQ|小黑屋|手机版|Archiver|fpga论坛|fpga设计论坛 ( 京ICP备20003123号-1 )

GMT+8, 2024-12-25 15:02 , Processed in 0.057346 second(s), 19 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表