串口接收实现"/>
Verilog 简单的串口接收实现
参考时钟频率为5Mhz;寄存器使用异步复位;
传输波特率 由时钟分频可得到9600、115200等典型波特率进行数据接收
以波特率9600 进行说明
T_clk5M = 200ns
T_B9600 ≈ 104166.667ns
9600 :baud_rate = T_B9600/T_clk5M ≈ 520.83
数据帧组成:一位起始位,八位数据位,一位校验位,一位(或两位)结束位。
模块带有一个开关使能信号
以下代码:
1.不考虑奇偶校验位
2.不考虑数据FIFO缓存防堵塞
/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*
* file name :uart_rx_in.v *
* description:a simple uart recive demo *
* author :菊月朔十 *
* 阳光开朗远离玉玉积极向上从不摸鱼菊月朔十 *
*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
module uart_rx_in(input wire clk , //5M时钟 input wire rstn , //低有效复位input wire enable , //高有效使能信号input wire [9:0] baud_rate , //波特率计数值input wire uart_rx_in , //异步uart_rx输入output reg [7:0] recive_in , //8bit接收数据output wire data_ready //数据有效指示标志脉冲);
//==================================================
reg [2:0] rx_sync ;
reg [9:0] baud_div_cnt ;
reg [3:0] recive_cnt ;
//==================================================
//对输入异步信号进行同步处理
always @(posedge clk or negedge rstn) beginif(!rstn)rx_sync <= 3'b0;else rx_sync <= {rx_sync[1:0],uart_rx_in};
end//波特率分频计数 接收波特率 = clk/baud_rate
always @(posedge clk or negedge rstn) beginif(!rstn)baud_div_cnt <= 10'b0;else if(!enable)baud_div_cnt <= 10'b0;else if(recive_cnt == 4'd10)baud_div_cnt <= 10'b0;else if(baud_div_cnt == baud_rate)baud_div_cnt <= 10'b0;else if(|recive_cnt)baud_div_cnt <= baud_div_cnt + 1'b1;
end//帧接收bit计数
always @(posedge clk or negedge rstn) beginif(!rstn)recive_cnt <= 4'b0;else if(!enable)recive_cnt <= 4'b0;else if(recive_cnt == 4'd10)recive_cnt <= 4'b0;else if(baud_div_cnt == baud_rate[9:1])recive_cnt <= recive_cnt + 1'b1;else if(recive_cnt == 4'b0)recive_cnt <= !rx_sync[2] & rx_sync[1];
end//数据的移位进 baud_rate[9:1] 中部采样
always @(posedge clk or negedge rstn) beginif(!rstn)recive_in <= 8'b0;else if(baud_div_cnt == baud_rate[9:1])recive_in <= {rx_sync[2],recive_in[7:1]};
end//接收完成,产生标志脉冲
assign data_ready = recive_cnt == 4'd10;endmodule
更多推荐
Verilog 简单的串口接收实现
发布评论