功能:使用串口发送模块,设计一个数据发送器,每10ms以115200的波特率发送一个数据,每次发送的数据比前一个数据大(计数器)
设置Send_Go作为数据发送控制
串口传输模块:
`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_Go,
Baud_set,
uart_tx,
Tx_done
);
input Clk ;
input Reset_n ;
input [7 : 0] Data ;
input Send_Go ;
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 Send_en ;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
Send_en <= 0 ;
else if(Send_Go)
Send_en <= 1 ;
else if(Tx_done)
Send_en <= 0 ;
//防止传输的数据发生变化,在传输之前先将数据寄存起来
reg [7:0] r_Data;
always@(posedge Clk )
if(Send_Go)
r_Data <= Data ;
else
r_Data <= r_Data ;
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;
end
else begin
case(bps_counter)
1 : uart_tx <= 0 ;
2 : uart_tx <= r_Data[0] ;
3 : uart_tx <= r_Data[1] ;
4 : uart_tx <= r_Data[2] ;
5 : uart_tx <= r_Data[3] ;
6 : uart_tx <= r_Data[4] ;
7 : uart_tx <= r_Data[5] ;
8 : uart_tx <= r_Data[6] ;
9 : uart_tx <= r_Data[7] ;
10 : uart_tx <= 1 ;
11 : begin uart_tx <= 1 ; Tx_done <= 1 'b1 ; end
default : uart_tx <= 1 ;
endcase
end
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
Tx_done <= 0 ;
else if((bps_clk == 1) && (bps_counter == 10))
Tx_done <= 1 ;
else
Tx_done <= 0 ;
endmodule
功能实现:
// Create Date: 2024/03/27 14:56:32
// Design Name: hilary
// Module Name: uary_byte_tx
module uart_tx_test(
Clk,
Reset_n,
uart_tx );
input Clk ;
input Reset_n ;
output uart_tx ;
reg Send_Go ;
reg [7:0] Data ;
uart_byte_tx uart_byte_tx(
.Clk(Clk),
.Reset_n(Reset_n),
.Data(Data),
.Send_Go(Send_Go),
.Baud_set(3 'd4),
.uart_tx(uart_tx),
.Tx_done(Tx_done)
);
reg [18:0] counter;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
counter <= 0 ;
else if(counter == 499999)
counter <= 0 ;
else
counter <= counter +1 'b1 ;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
Send_Go <= 0 ;
else if(counter <= 1)
Send_Go <= 1 ;
else
Send_Go <= 0 ;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
Data <= 0 ;
else if(Tx_done)
Data <= Data + 1 'b1 ;
endmodule
仿真测试:
`timescale 1ns / 1ns
// Create Date: 2024/04/02 10:53:01
// Design Name: hilary
// Module Name: uart_tx_test_tb
module uart_tx_test_tb();
reg Clk ;
reg Reset_n ;
wire uart_tx ;
uart_tx_test uart_tx_test(
.Clk(Clk),
.Reset_n(Reset_n),
.uart_tx(uart_tx)
);
initial Clk = 1 ;
always#10 Clk =~Clk ;
initial begin
Reset_n = 0;
#201
Reset_n = 1 ;
#50000000
$stop;
end
endmodule