`timescale 1ns / 1ns
//
module uart_tx(
clk,
rst_n,
data[7:0],
send_en,
band_set,
uart_tx,
tx_done
);
input clk ;
input rst_n ;
input [7:0] data ;
input send_en ;
input [2:0] band_set ;
output reg uart_tx;
output reg tx_done;
reg [17:0] div_cnt ; //
reg [17:0] bps_DR ; //不同的波特率对应不同的bps_DR
reg [3:0] bps_cnt ;
wire bpis_clk;
assign bps_clk=(div_cnt==1);
always @(*)begin
case (band_set)
0:bps_DR = 1_000_000_000/9600/20; //波特率等于9600时,一个比特需要多少个时钟周期
1:bps_DR = 1_000_000_000/19200/20;
2:bps_DR = 1_000_000_000/38400/20;
3:bps_DR = 1_000_000_000/57600/20;
4:bps_DR = 1_000_000_000/115200/20;
default:bps_DR = 1_000_000_000/9600/20;
endcase
end
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
div_cnt <= 0;
else if(send_en)
if(div_cnt ==bps_DR-1)
div_cnt<= 0;
else
div_cnt <=div_cnt +1;
// end
else
div_cnt <=0;
end
always @(posedge clk or negedge rst_n)
if(!rst_n)
bps_cnt <= 0;
else if(send_en)begin
if (bps_clk)begin
if(bps_cnt == 12-1)
bps_cnt <= 0;
else
bps_cnt <=bps_cnt +1 ;
end
end
else
bps_cnt <= 0;
// end
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
uart_tx <=1 ;
tx_done <=0 ;
end
else begin
case(bps_cnt)
1:begin uart_tx <=0;tx_done <= 0;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;end
default:uart_tx<=1;
endcase
end
end
endmodule
`timescale 1ns /1ps
module tb_uart_tx;
reg clk ;
reg rst_n ;
reg [7:0] data ;
reg send_en ;
reg [2:0] band_set ;
wire uart_tx ;
wire tx_done ;
uart_tx uus(
.clk (clk ),
.rst_n (rst_n ),
.data (data ),
.send_en (send_en ),
.band_set (band_set),
.uart_tx (uart_tx ),
.tx_done (tx_done )
);
initial clk =0;
always #10 clk=~clk;
initial begin
rst_n =0;
data=0;
send_en=0;
band_set=4;
#201
rst_n =1;
#100
send_en=1;
data = 01010111;
#20
@(posedge tx_done);
send_en =0;
#2000
send_en=1;
data = 01110101;
#20
@(posedge tx_done);
#20000;
$stop;
end
endmodule
串口发送测试代码