集成电路技术分享

 找回密码
 我要注册

QQ登录

只需一步,快速开始

搜索
查看: 1277|回复: 1

verilog简单实现串口(精简版)

[复制链接]
fpga_feixiang 发表于 2018-10-17 15:41:37 | 显示全部楼层 |阅读模式
//uart 2017.10.9  发送接收到的数据
//波特率9600 8个数据位 一个停止位 无奇偶校验
module uart(
           clk,   //50Mhz
           rst_n, //reset
           rx,    //input   
           tx     //ouptut   
);
input clk,rst_n;
input rx;
output reg tx;

//-----------------检测是否有数据来--------
//边沿检测  
wire rx_start;
reg rx1;
always@(posedge clk or negedge rst_n)
begin
    if(!rst_n) rx1<=1'b0;
    else rx1<=rx;
end
assign rx_start = ~rx & rx1;
//-------------------波特率控制------------
wire bps_start;
reg bps_start_rx,bps_start_tx;
reg [3:0] rx_num,tx_num;         // 2^4-1=15
always@(posedge clk or negedge rst_n)
begin
    if(!rst_n)
       begin
        bps_start_rx<=1'b0;
        bps_start_tx<=1'b0;
       end
    else if(rx_start) bps_start_rx<=1'b1;
    //接收完数据后 开始发送数据
    else if(rx_num==10)
       begin  
         bps_start_rx<=1'b0;
         bps_start_tx<=1'b1;
       end
    //发送完数据后 无需产生波特率
    else if(tx_num==10)
         bps_start_tx<=1'b0;
end
assign bps_start = bps_start_rx|bps_start_tx;
//------------------产生波特率--------------
//9600
parameter bps_cnt=5208;    //50Mhz / 9600 = 5208.3......
parameter bps_cnt_half=2604;
reg [12:0] cnt;
always@(posedge clk or negedge rst_n)
begin
    if(!rst_n) cnt<=13'b0;
    else if(cnt==bps_cnt) cnt<=13'b0;
    else if(bps_start) cnt<=cnt+1'b1;
    else cnt<=13'b0;
end

//--------接收寄存器 发送寄存器------------
reg [7:0] rx_data,tx_data;
//---------------------接收数据--------------
//receive
always@(posedge clk or negedge rst_n)
begin
    if(!rst_n)
     begin
      rx_num<=4'b0;
      rx_data<=8'b0;
     end
    else if(cnt==bps_cnt_half)
     begin
                if(bps_start_rx)
                        begin
                         rx_num<=rx_num+1'b1;
                         case(rx_num)
                                 1:rx_data[0]<=rx;
                                 2:rx_data[1]<=rx;
                                 3:rx_data[2]<=rx;
                                 4:rx_data[3]<=rx;
                                 5:rx_data[4]<=rx;
                                 6:rx_data[5]<=rx;
                                 7:rx_data[6]<=rx;
                                 8:rx_data[7]<=rx;
                                 9:tx_data<=rx_data;
                         endcase
                        end
         end
         else if(rx_num==10) rx_num<=4'b0;

end
//---------------------发送数据--------------
//transport
always@(posedge clk or negedge rst_n)
begin
    if(!rst_n) tx_num<=4'b0;
    else if(cnt==bps_cnt_half)
       begin
                if(bps_start_tx)
                begin
                 tx_num<=tx_num+1'b1;
                 case(tx_num)
                         0:tx<=1'b0;
                         1:tx<=tx_data[0];
                         2:tx<=tx_data[1];
                         3:tx<=tx_data[2];
                         4:tx<=tx_data[3];
                         5:tx<=tx_data[4];
                         6:tx<=tx_data[5];
                         7:tx<=tx_data[6];
                         8:tx<=tx_data[7];
                         9:tx<=1'b1;
                  endcase
                 end
                else tx<=1'b1;
            end
         else if(tx_num==10) tx_num<=4'b0;
end

endmodule
---------------------
zhangyukun 发表于 2018-10-18 09:42:14 | 显示全部楼层
verilog简单实现串口(精简版)
您需要登录后才可以回帖 登录 | 我要注册

本版积分规则

关闭

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

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

GMT+8, 2025-5-1 14:52 , Processed in 0.056308 second(s), 19 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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