UART协议及其verilog实现(2)
#学习记录#
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
原文地址:https://blog.csdn.net/2301_76563419/article/details/138557667
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!