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 [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 

 

你可能感兴趣的:(FPGA,串口,FPGA,verilog,DE2,uart)