1.串口通信模块设计的目的:发送数据,因此需要一个数据输入端口;
2.串口通信:支持不同的波特率,所以需要一个波特率设置端口;
3.串口通信的本质:将8位的并行数据通过一根信号线,在不同时刻传输并行数据的不同位,通过不同时刻,最终将8位数据全部传出;
4.串口通信以1位的低电平标志串行传输的开始,待9位数据传输完成之后,在以1位高电平标志传输结束;
5.控制信号EN:控制并转串模块什么时候开始工作,什么时候一个数据发送完成,所以需要一个开始信号,一个结束信号。
设计:
`timescale 1ns / 1ns
// Create Date: 2024/03/27 14:56:32
// Design Name: hilary
// Module Name: uary_byte_tx
module uart_byte_tx(
Clk,
Reset_n,
Data,
Send_en,
Baud_set,
uart_tx,
Tx_done
);
input Clk ;
input Reset_n ;
input [7 : 0] Data ;
input Send_en ;
input [2 : 0] Baud_set ;
output reg uart_tx ;
output reg Tx_done ;
//Baud_set = 0 ,波特率=9600;
//Baud_set = 1 ,波特率=19200;
//Baud_set = 2 ,波特率=38400;
//Baud_set = 3 ,波特率=57600;
//Baud_set = 4 ,波特率=115200;
//bps_DR = 1000000000/波特率/20
reg [18:0] bps_DR ;
always@(*)
case(Baud_set)
0 : bps_DR = 1000000000/9600/20 ;
1 : bps_DR = 1000000000/19200/20 ;
2 : bps_DR = 1000000000/38400/20 ;
3 : bps_DR = 1000000000/57600/20 ;
4 : bps_DR = 1000000000/115200/20 ;
default : bps_DR = 1000000000/9600/20 ;
endcase
reg [17:0] div_counter ;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
div_counter <= 0 ;
else if(Send_en)begin
if(div_counter == bps_DR - 1 )
div_counter <= 0 ;
else
div_counter <= div_counter +1 'b1 ;
end
else
div_counter <= 0 ;
reg [3:0] bps_counter ;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
bps_counter <= 0 ;
else if(Send_en)begin
if(div_counter == 1 )begin
if (bps_counter == 12)
bps_counter <= 0 ;
else
bps_counter <= bps_counter + 1 'b1 ;
end
end
else
bps_counter <= 0 ;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)begin
uart_tx <= 1'b1;
Tx_done <= 0;
end
else begin
case(bps_counter)
1 : begin uart_tx <= 0 ; Tx_done <= 1 'b0 ; end
2 : uart_tx <= Data[0] ;
3 : uart_tx <= Data[1] ;
4 : uart_tx <= Data[2] ;
5 : uart_tx <= Data[3] ;
6 : uart_tx <= Data[4] ;
7 : uart_tx <= Data[5] ;
8 : uart_tx <= Data[6] ;
9 : uart_tx <= Data[7] ;
11 : uart_tx <= 1 ;
12 : begin uart_tx <= 1 ; Tx_done <= 1 'b1 ; end
default : uart_tx <= 1 ;
endcase
end
endmodule
测试仿真:
`timescale 1ns / 1ns
module uart_byte_tx_tb() ;
reg Clk ;
reg Reset_n;
reg [7:0] Data;
reg Send_en;
reg [2:0] Baud_set;
wire uart_tx;
wire Tx_done;
uart_byte_tx uart_byte_tx(
.Clk(Clk),
.Reset_n(Reset_n),
.Data(Data),
.Send_en(Send_en),
.Baud_set(Baud_set),
.uart_tx(uart_tx),
.Tx_done(Tx_done)
);
initial Clk = 1;
always#10 Clk = ~Clk;
initial begin
Reset_n = 0;
Data = 0;
Send_en = 0;
Baud_set = 4;
#201;
Reset_n = 1;
#100;
Data = 8 'h57 ;
Send_en = 1;
#20
@(posedge Tx_done);
Send_en = 0;
#20000;
Data = 8 'h75 ;
Send_en = 1;
#20
@(posedge Tx_done);
#20000;
Send_en = 0;
$stop;
end
endmodule
加入脉冲标记bps_clk:
`timescale 1ns / 1ns
// Create Date: 2024/03/27 14:56:32
// Design Name: hilary
// Module Name: uary_byte_tx
module uart_byte_tx(
Clk,
Reset_n,
Data,
Send_en,
Baud_set,
uart_tx,
Tx_done
);
input Clk ;
input Reset_n ;
input [7 : 0] Data ;
input Send_en ;
input [2 : 0] Baud_set ;
output reg uart_tx ;
output reg Tx_done ;
//Baud_set = 0 ,波特率=9600;
//Baud_set = 1 ,波特率=19200;
//Baud_set = 2 ,波特率=38400;
//Baud_set = 3 ,波特率=57600;
//Baud_set = 4 ,波特率=115200;
//bps_DR = 1000000000/波特率/20
reg [18:0] bps_DR ;
always@(*)
case(Baud_set)
0 : bps_DR = 1000000000/9600/20 ;
1 : bps_DR = 1000000000/19200/20 ;
2 : bps_DR = 1000000000/38400/20 ;
3 : bps_DR = 1000000000/57600/20 ;
4 : bps_DR = 1000000000/115200/20 ;
default : bps_DR = 1000000000/9600/20 ;
endcase
wire bps_clk;
assign bps_clk = (div_counter ==1) ;
reg [17:0] div_counter ;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
div_counter <= 0 ;
else if(Send_en)begin
if(div_counter == bps_DR - 1 )
div_counter <= 0 ;
else
div_counter <= div_counter +1 'b1 ;
end
else
div_counter <= 0 ;
reg [3:0] bps_counter ;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
bps_counter <= 0 ;
else if(Send_en)begin
if(bps_clk )begin
if (bps_counter == 11)
bps_counter <= 0 ;
else
bps_counter <= bps_counter + 1 'b1 ;
end
end
else
bps_counter <= 0 ;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)begin
uart_tx <= 1'b1;
Tx_done <= 0;
end
else begin
case(bps_counter)
1 : begin uart_tx <= 0 ; Tx_done <= 1 'b0 ; end
2 : uart_tx <= Data[0] ;
3 : uart_tx <= Data[1] ;
4 : uart_tx <= Data[2] ;
5 : uart_tx <= Data[3] ;
6 : uart_tx <= Data[4] ;
7 : uart_tx <= Data[5] ;
8 : uart_tx <= Data[6] ;
9 : uart_tx <= Data[7] ;
10 : uart_tx <= 1 ;
11 : begin uart_tx <= 1 ; Tx_done <= 1 'b1 ; end
default : uart_tx <= 1 ;
endcase
end
endmodule
仿真代码同上