UART协议及其verilog实现(2)

发布于:2024-05-09 ⋅ 阅读:(24) ⋅ 点赞:(0)

#学习记录#

1 UART

 在UART协议及其verilog实现(1)_uart协议verilog-CSDN博客这篇文章中介绍了UART发送数据的代码,UART接收端的代码如下。

2 verilog实现

2.1 发送端代码

`timescale 1ns / 1ps
//
// Company: 
// Engineer:mr-pn-junction 
// 
// Create Date: 2024/04/21 20:52:15
// Design Name: 
// Module Name: uart_tx
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//
 
 
module uart_tx(
    input clk,
    input rst_n,
    input start,
    input [7:0] data,
    output reg rs232_tx,
    output reg done
    );
    reg [7:0] r_data;
    reg state;
    reg [12:0] baud_cnt;
    reg bit_flag;
    reg [3:0] bit_cnt;
//=======================r_data=================//
always@(posedge clk or negedge rst_n)begin
    if(!rst_n)
        r_data<=8'b0;
    else if(start)
        r_data<=data;
    else
        r_data<=r_data;
end
//=====================state==================//
always@(posedge clk or negedge rst_n)begin
    if(!rst_n)
        state<=1'b0;
    else if(start)
        state<=1'b1;
    else if(done)
        state<=1'b0;
    else
        state<=state;
end
//======================baud_cnt===================//
always@(posedge clk or negedge rst_n)begin
    if(!rst_n)
        baud_cnt<=13'd0;
    else if(state)begin
        if(baud_cnt==13'd28)
            baud_cnt<=13'd0;
        else
            baud_cnt<=baud_cnt+13'd1;
    end
    else
        baud_cnt<=13'd0;
    
end
//================bit_flag===========================//
always@(posedge clk or negedge rst_n)begin
    if(!rst_n)
        bit_flag<=1'b0;
    else if(baud_cnt == 'd1)
        bit_flag<=1'b1;
    else
        bit_flag<=1'b0;
end
//======================bit_cnt===================//
always@(posedge clk or negedge rst_n)begin
    if(!rst_n)
        bit_cnt<=4'b0;
    else if(bit_flag)
        bit_cnt<=bit_cnt+4'd1;
    else if(bit_cnt ==4'd10)
        bit_cnt<= 4'b0;
    else
        bit_cnt<=bit_cnt;
        
    
end
//============================rs232_tx========================//
always@(posedge clk or negedge rst_n)begin
    if(!rst_n)
        rs232_tx<=1'b1;
    else if(state)begin
        if(bit_flag)begin
            case(bit_cnt)
                4'd0: rs232_tx<=1'b0;
                4'd1: rs232_tx<=r_data[0];
                4'd2: rs232_tx<=r_data[1];
                4'd3: rs232_tx<=r_data[2];
                4'd4: rs232_tx<=r_data[3];
                4'd5: rs232_tx<=r_data[4];
                4'd6: rs232_tx<=r_data[5];
                4'd7: rs232_tx<=r_data[6];
                4'd8: rs232_tx<=r_data[7];
                4'd9: rs232_tx<=1'b1;
                default rs232_tx<=1'b1;
                endcase
        end
        else
            rs232_tx<=rs232_tx;
       end
    else
        rs232_tx<=1'b1;
    
end
//================================done================//
always@(posedge clk or negedge rst_n)begin
    if(!rst_n)
        done<=1'b0;
    else if(bit_flag &&(bit_cnt == 4'd9))
        done<=1'b1;
    else
        done<=1'b0;
     
end
    
endmodule

2.2 接收端代码

`timescale 1ns/1ps
//mr-pn-junction

module uart_rx(
	input           clk,
	input           rst_n,
	input           rs232,
	output reg[7:0] rx_data,
	output reg      done
);
	reg             rs232_t;
	reg             rs232_t1;
	reg             rs232_t2;
	reg     [4:0]   bit_cnt;
	reg             bit_flag;
	reg             state;
	reg     [12:0]  baud_cnt;
	wire            nege;
//?????
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)begin
		rs232_t<=1'b1;
		rs232_t1<=1'b1;
		rs232_t2<=1'b1;
	end
	else begin
		rs232_t<=rs232;
		rs232_t1<=rs232_t;
		rs232_t2<=rs232_t1;
	end
end

//nege
assign nege=!rs232_t1 && rs232_t2;
//state
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)
		state<=1'b0;
	else if(nege)
		state<=1'b1;
	else if(done)
		state<=1'b0;
	else
		state<=state;
end
//baud_cnt
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)
		baud_cnt<=13'd0;
	else if(state)begin
		if(baud_cnt ==13'd28)
			baud_cnt<=13'd0;
		else
			baud_cnt<=baud_cnt+13'd1;
	end
	else
		baud_cnt<=13'd0;
		
end
//bit_flag
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)
		bit_flag<=1'b0;
	else if(baud_cnt == 13'd14)
		bit_flag<=1'b1;
	else
		bit_flag<=1'b0;
end
//bit_cnt
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)
		bit_cnt<=4'd0;
	else if(bit_flag)begin
		if(bit_cnt == 4'd10)
			bit_cnt<=4'd0;
		else
			bit_cnt<=bit_cnt+4'd1;
	end
	else
		bit_cnt<=bit_cnt;
end
//rx_data
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)
		rx_data<=8'b0;
	else if (state)begin
		if(bit_flag)begin
			case(bit_cnt)
				4'd1:rx_data[0] <=rs232_t2;
				4'd2:rx_data[1] <=rs232_t2;
				4'd3:rx_data[2] <=rs232_t2;
				4'd4:rx_data[3] <=rs232_t2;
				4'd5:rx_data[4] <=rs232_t2;
				4'd6:rx_data[5] <=rs232_t2;
				4'd7:rx_data[6] <=rs232_t2;
				default:rx_data<=rx_data;
			endcase
		end
		else
			rx_data<=rx_data;
		
	end
	else
		rx_data<=rx_data;
		
end
//done
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)
		done<=1'b0;
	else if(bit_flag && (bit_cnt ==4'd10))
		done<=1'b1;
	else
		done<=1'b0;
		
end




endmodule

2.3 testbench

`timescale 1ns / 1ps
//
// Company: 
// Engineer: mr-pn-junction
// 
// Create Date: 2024/04/26 10:45:26
// Design Name: 
// Module Name: tb_uart_tx
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module tb_uart( );
    reg clk;
    reg rst_n;
    reg start;
    reg [7:0] data;
    wire rs232_tx;
    wire done;

   
    wire [7:0] rx_data;
initial clk=1'b0;
always #10 clk=~clk;
initial begin
    rst_n=1'b0;
    start=1'b0;
    data='d0;
    #100
    rst_n=1'b1;
    #200
    data='h55;
    start=1'b1;
    #20
    start=1'b0;
    #20000
    data='h58;
    start=1'b1;
    #20
    start=1'b0;
    #20000
    $stop;
    
end
uart_rx u_uart_rx(
	.clk(clk),
	.rst_n(rst_n),
	.rs232(rs232_tx),
	.done(),
	.rx_data(rx_data)
);

uart_tx u_uart(
    .clk(clk),
    .rst_n(rst_n),
    .start(start),
    .data(data),
    .rs232_tx(rs232_tx),
    .done(done)

);
endmodule

3 仿真结果

参考文献

[1] FPGA(UART通信协议,手把手学会分析时序并写出UART协议)_哔哩哔哩_bilibili