#学习记录#
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)beginif(!rst_n)r_data<=8'b0;else if(start)r_data<=data;elser_data<=r_data;
end
//=====================state==================//
always@(posedge clk or negedge rst_n)beginif(!rst_n)state<=1'b0;else if(start)state<=1'b1;else if(done)state<=1'b0;elsestate<=state;
end
//======================baud_cnt===================//
always@(posedge clk or negedge rst_n)beginif(!rst_n)baud_cnt<=13'd0;else if(state)beginif(baud_cnt==13'd28)baud_cnt<=13'd0;elsebaud_cnt<=baud_cnt+13'd1;endelsebaud_cnt<=13'd0;end
//================bit_flag===========================//
always@(posedge clk or negedge rst_n)beginif(!rst_n)bit_flag<=1'b0;else if(baud_cnt == 'd1)bit_flag<=1'b1;elsebit_flag<=1'b0;
end
//======================bit_cnt===================//
always@(posedge clk or negedge rst_n)beginif(!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;elsebit_cnt<=bit_cnt;end
//============================rs232_tx========================//
always@(posedge clk or negedge rst_n)beginif(!rst_n)rs232_tx<=1'b1;else if(state)beginif(bit_flag)begincase(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;endcaseendelsers232_tx<=rs232_tx;endelsers232_tx<=1'b1;end
//================================done================//
always@(posedge clk or negedge rst_n)beginif(!rst_n)done<=1'b0;else if(bit_flag &&(bit_cnt == 4'd9))done<=1'b1;elsedone<=1'b0;endendmodule
2.2 接收端代码
`timescale 1ns/1ps
//mr-pn-junctionmodule 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)beginif(!rst_n)beginrs232_t<=1'b1;rs232_t1<=1'b1;rs232_t2<=1'b1;endelse beginrs232_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)beginif(!rst_n)state<=1'b0;else if(nege)state<=1'b1;else if(done)state<=1'b0;elsestate<=state;
end
//baud_cnt
always@(posedge clk or negedge rst_n)beginif(!rst_n)baud_cnt<=13'd0;else if(state)beginif(baud_cnt ==13'd28)baud_cnt<=13'd0;elsebaud_cnt<=baud_cnt+13'd1;endelsebaud_cnt<=13'd0;end
//bit_flag
always@(posedge clk or negedge rst_n)beginif(!rst_n)bit_flag<=1'b0;else if(baud_cnt == 13'd14)bit_flag<=1'b1;elsebit_flag<=1'b0;
end
//bit_cnt
always@(posedge clk or negedge rst_n)beginif(!rst_n)bit_cnt<=4'd0;else if(bit_flag)beginif(bit_cnt == 4'd10)bit_cnt<=4'd0;elsebit_cnt<=bit_cnt+4'd1;endelsebit_cnt<=bit_cnt;
end
//rx_data
always@(posedge clk or negedge rst_n)beginif(!rst_n)rx_data<=8'b0;else if (state)beginif(bit_flag)begincase(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;endcaseendelserx_data<=rx_data;endelserx_data<=rx_data;end
//done
always@(posedge clk or negedge rst_n)beginif(!rst_n)done<=1'b0;else if(bit_flag && (bit_cnt ==4'd10))done<=1'b1;elsedone<=1'b0;endendmodule
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 beginrst_n=1'b0;start=1'b0;data='d0;#100rst_n=1'b1;#200data='h55;start=1'b1;#20start=1'b0;#20000data='h58;start=1'b1;#20start=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