串口接收模块(verilog) 波特率115200

我来分享一下uart协议之接收verilog代码

顶层实例化

`timecale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 17:38:36 11/07/2017
// Design Name: chendog
// Module Name: uart_receive_top
// Project Name: uart_receive
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module uart_receive_top(
input wire clk, //时钟信号
input wire rst_n, //复位信号
input wire receive, //接收信号
output wire [7:0] data //接收数据
);

wire cnt_start; //开始计数
wire bps_sig; //读数据中间位置
wire recei_nege; //下降沿开始接收数据

/////////////////////////////////////波特率设置模块
bps_set bps_set1(
.clk(clk),
.rst_n(rst_n),
.receive(receive),
.cnt_start(cnt_start),
.bps_sig(bps_sig),
.recei_nege(recei_nege)
);

////////////////////////////////////数据接收状态转换
receive_fsm receive_fsm1(
.clk(clk),
.rst_n(rst_n),
.receive(receive),
.bps_sig(bps_sig),
.recei_nege(recei_nege),
.cnt_start(cnt_start),
.data(data)
);

endmodule

波特率设置

module bps_set(
input wire clk,
input wire rst_n,
input wire receive,
input wire cnt_start,
output wire bps_sig,
output wire recei_nege
);

///////////////////////////////////////////////下降沿检测
reg receive1;
reg receive2;

always@(posedge clk or negedge rst_n)
begin
if(!rst_n) begin
receive1 <= 1'b0;
receive2 <= 1'b0;
end
else begin
receive1 <= receive;
receive2 <= receive1;
end
end

assign recei_nege = receive2 & ~receive1;


/////////////////////////////////////////////////分频计数
parameter CONSTANT1 = 9'd434;  //波特率115200  434 = 50m/115200

reg [8:0] cnt;

always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
cnt <= 9'd0;
else if(cnt_start) begin
if(cnt == CONSTANT1 - 1'b1)
cnt <= 9'd0;
else
cnt <= cnt + 1'b1;
end
else
cnt <= cnt;
end

assign bps_sig = (cnt == CONSTANT1 / 2)? 1'b1:1'b0; //采集计数中间位置

endmodule

接收状态机

module receive_fsm(
input wire clk,
input wire rst_n,
input wire receive,
input wire bps_sig,
input wire recei_nege,
output reg cnt_start,
output reg [7:0] data
);

reg [3:0] state;

////////////////////////////////////////////一段式状态机
always@(posedge clk or negedge rst_n)
begin
if(!rst_n) begin
cnt_start <= 1'b0;
state <= 4'd0;
data <= 8'd0;
end
else case(state)
0: if(recei_nege) begin //等待数据线下降沿 下降沿到来 进入计数状态
state <= 4'd1;
cnt_start <= 1'b1;
data <= 8'd0;
end

else begin
state <= 4'd0;
cnt_start <= 1'b0;
data <= 8'd0;
end

1: if(bps_sig) begin //第一位 起始位
state <= state + 4'd1;
end
else begin
state <= state;
end

2,3,4,5,6,7,8,9: //数据位开始接收
if(bps_sig) begin
state <= state + 4'd1;
data[state - 4'd2] <= receive;
end

else begin
state <= state;
end

10,11:if(bps_sig) begin //停止位与校验位
state <= state + 4'd1;
end

else begin
state <= state;
end
12:if(bps_sig) begin //完成一次接收 停止计数 回到state = 0
state <= 4'b0;
cnt_start <= 1'b0;
end
else begin
state <= state;
end
endcase
end

endmodule

纯代码与注释,有问题联系qq:1424307272

上一篇:atitit.404错误的排查流程总结vOa6


下一篇:CSS3+HTML5特效2 - 翻转效果