1 源代码
2 module uart_byte_tx(
3 clk,
4 reset_n,
5 data,
6 send_en,
7 baud_set,
8 uart_tx,
9 tx_done
10 );
11 input clk;
12 input reset_n;
13 input [7:0] data;
14 input send_en;
15 input [2:0] baud_set;
16 output reg uart_tx;
17 output reg tx_done;
18 //设置可选择选择波特率的模式
19 reg [17:0] bps_DR;
20 always@(*)
21 case(baud_set)
22 0:bps_DR=1000000000/9600/20;
23 1:bps_DR=1000000000/19200/20;
24 2:bps_DR=1000000000/38400/20;
25 3:bps_DR=1000000000/57600/20;
26 4:bps_DR=1000000000/115200/20;
27 default:bps_DR=1000000000/9600/20;
28 endcase
29
30
31 //设置分频计数器,满足最低的波特率的位数,18位。
32 reg [17:0] div_cnt;
33 always @(posedge clk or negedge reset_n)
34 if(!reset_n)
35 div_cnt<=0;
36 else if(send_en)begin
37 if(div_cnt==bps_DR-1)
38 div_cnt<=0;
39 else
40 div_cnt<=div_cnt+1'b1;
41 end
42 else
43 div_cnt<=0;
44
45 wire bps_clk;
46 assign bps_clk=(div_cnt==1);
47 //开始讲每个时间段连接起来。
48 reg [3:0] bps_cnt;
49 always@(posedge clk or negedge reset_n)
50 if(!reset_n)
51 bps_cnt<=0;
52 //1、这里的等于div_cnt==1是为了让计数器从0计数到1时时间比较段,二不产生太大延迟,
53 //2、加入send_en是为了让计数完及时清零。
54 else if(send_en)begin
55 //每次计数到11清零,其他时间进行加一的操作。
56 if(div_cnt==1) begin
57 if(bps_cnt==11)
58 bps_cnt<=0;
59 else
60 bps_cnt<=bps_cnt+1'b1;
61 end
62 end
63 else
64 bps_cnt<=0;
65 //开始发送数据
66 always@(posedge clk or negedge reset_n)
67 if(!reset_n)begin
68 uart_tx<=1'b1;
69 tx_done<=0;
70 end
71 else case(bps_cnt)
72 //如果从0开始的话,会在中间间隔时间(空窗期),使得uart_tx=0;
73 //因为发送初始位置时(0时刻),就让uart_tx<=0了.
74 1:begin uart_tx<=0;tx_done<=0; end
75 2:uart_tx<=data[0];
76 3:uart_tx<=data[1];
77 4:uart_tx<=data[2];
78 5:uart_tx<=data[3];
79 6:uart_tx<=data[4];
80 7:uart_tx<=data[5];
81 8:uart_tx<=data[6];
82 9:uart_tx<=data[7];
83 10:uart_tx<=1;
84 11:begin uart_tx<=1;tx_done<=1;end
85 default uart_tx<=1;
86 endcase
87
88 endmodule
89
90 仿真代码
91 `timescale 1ns/1ns
92 module uart_byte_tx_tb();
93 reg clk;
94 reg reset_n;
95 reg [7:0] data;
96 reg send_en;
97 reg [2:0] baud_set;
98 wire uart_tx;
99 wire tx_done;
100 uart_byte_tx uart_byte_tx_inst0(
101 .clk(clk),
102 .reset_n(reset_n),
103 .data(data),
104 .send_en(send_en),
105 .baud_set(baud_set),
106 .uart_tx(uart_tx),
107 .tx_done(tx_done)
108 );
109 initial clk=1;
110 always #10 clk=!clk;
111
112 initial begin
113 reset_n=0;
114 data=0;
115 baud_set=4;
116 send_en=0;
117 #201;
118 reset_n=1;
119 #20;
120
121 data=8'h57;
122 send_en=1;
123
124 @(posedge tx_done)
125 send_en=0;
126 #2000;
127 data=8'h75;
128 send_en=1;
129 #20;
130 @(posedge tx_done)
131 send_en=0;
132 #20000;
133 $stop;
134 end
135
136
137 endmodule