verilog简单实现串口

//uart 2017.10.7  发送接收到的数据 
//波特率9600 一个停止位 无奇偶校验
//DE2板子
/*
rx GPIO_K25 0 left   -----tx
tx GPIO_K26 1 right  -----rx
GND  右边第6 或者倒数第6
*/

//复位不成功 ????? 复位按键有问题 靠右按即可复位 
//特别注意 如果一个条件中同时给一个寄存器赋不同的值 结果不确定 
//以下是错误代码例子   tx_num 
//同时赋值  这里加一 下面赋值0
/*
		 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:begin tx<=1'b1; tx_num<=4'b0; end
*/
//一些小的算法问题 画个时序图 标出各个点寄存器的值 
//对照程序看是否正确 特别是需要判断且改变状态的点
//以下是代码
//----------------------代码------------------
module uart(
           clk,   //50Mhz
           rst_n, //reset
           rx,    //input    
           tx,    //ouptut   
           sw     //测试是否收到数据
);
input clk,rst_n;
input rx;
output reg tx;

//测试是否收到数据
output wire [7:0] sw;

//-----------------检测是否有数据来--------
//边沿检测  
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;
//测试是否收到数据
assign sw=rx_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 

 

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大米粥哥哥

感谢认可!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值