fpga_feixiang 发表于 2018-10-17 15:41:37

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

//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 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 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 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<=rx;
                               2:rx_data<=rx;
                               3:rx_data<=rx;
                               4:rx_data<=rx;
                               5:rx_data<=rx;
                               6:rx_data<=rx;
                               7:rx_data<=rx;
                               8:rx_data<=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;
                       2:tx<=tx_data;
                       3:tx<=tx_data;
                       4:tx<=tx_data;
                       5:tx<=tx_data;
                       6:tx<=tx_data;
                       7:tx<=tx_data;
                       8:tx<=tx_data;
                       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]
查看完整版本: verilog简单实现串口(精简版)