1 //使用串口发送5个字节的数据到电脑上面
2 //1、ADC,采样结果是12位的,怎么使用串口进行发送。
3 //2、16位的数据,怎杨通过串口发送
4 //有多个字节的数据通过串口发送
5 //uart协议规定了只能发送6,7,8位数据。
6 //两种情况,1、没有开始发送(上一次已经发送完成,新的40位数据的发送请求没有出现)
7 //2、来了40位的发送请求信号,依次发送数据的状态。
8 //1、发送八位数据的底层模块
9 //源代码
10 module uart_byte_tx(
11 clk,
12 reset_n,
13 data,
14 send_go,
15 baud_set,
16 uart_tx,
17 tx_done
18 );
19 input clk;
20 input reset_n;
21 input [7:0] data;
22 input send_go;
23 input [2:0] baud_set;
24 output reg uart_tx;
25 output reg tx_done;
26 //设置可选择选择波特率的模式
27 reg [17:0] bps_DR;
28 always@(*)
29 case(baud_set)
30 0:bps_DR=1000000000/9600/20;
31 1:bps_DR=1000000000/19200/20;
32 2:bps_DR=1000000000/38400/20;
33 3:bps_DR=1000000000/57600/20;
34 4:bps_DR=1000000000/115200/20;
35 default:bps_DR=1000000000/9600/20;
36 endcase
37 reg send_en;
38 always@(posedge clk or negedge reset_n)
39 if(!reset_n)
40 send_en<=0;
41 else if(send_go)
42 send_en<=1;
43 else if(tx_done)
44 send_en<=0;
45
46 reg [7:0] r_data;
47 always@(posedge clk or negedge reset_n)
48 if(!reset_n)
49 r_data<=0;
50 else if(send_go)
51 r_data<=data;
52 else
53 r_data<=r_data;
54 //设置分频计数器,满足最低的波特率的位数,18位。
55 reg [17:0] div_cnt;
56 always @(posedge clk or negedge reset_n)
57 if(!reset_n)
58 div_cnt<=0;
59 else if(send_en)begin
60 if(div_cnt==bps_DR-1)
61 div_cnt<=0;
62 else
63 div_cnt<=div_cnt+1'b1;
64 end
65 else
66 div_cnt<=0;
67
68 wire bps_clk;
69 assign bps_clk=(div_cnt==1);
70 //开始将每个时间段连接起来。
71 reg [3:0] bps_cnt;
72 always@(posedge clk or negedge reset_n)
73 if(!reset_n)
74 bps_cnt<=0;
75 //1、这里的等于div_cnt==1是为了让计数器从0计数到1时时间比较段,二不产生太大延迟,
76 //2、加入send_en是为了让计数完及时清零。
77 else if(send_en)begin
78
79 if(bps_clk) begin//每次计数到11清零,其他时间进行加一的操作。
80 if(bps_cnt==11)
81 bps_cnt<=0;
82 else
83 bps_cnt<=bps_cnt+1'b1;
84 end
85 end
86 else
87 bps_cnt<=0;
88 //开始发送数据
89 always@(posedge clk or negedge reset_n)
90 if(!reset_n)
91 uart_tx<=1'b1;
92 else case(bps_cnt)
93
94 //如果从0开始的话,会在中间间隔时间(空窗期),使得uart_tx=0;
95 //因为发送初始位置时(0时刻),就让uart_tx<=0了.
96 1:uart_tx<=0;
97 2:uart_tx<=r_data[0];
98 3:uart_tx<=r_data[1];
99 4:uart_tx<=r_data[2];
100 5:uart_tx<=r_data[3];
101 6:uart_tx<=r_data[4];
102 7:uart_tx<=r_data[5];
103 8:uart_tx<=r_data[6];
104 9:uart_tx<=r_data[7];
105 10:uart_tx<=1;
106 11:uart_tx<=1;
107 default uart_tx<=1;
108 endcase
109 //这个也会忘了
110 //将tx_done单独书写,在底层书写模块。
111 always@(posedge clk or negedge reset_n)
112 if(!reset_n)
113 tx_done<=0;
114 else if((bps_clk==1)&&(bps_cnt==10))
115 tx_done<=1;
116 else
117 tx_done<=0;
118
119 endmodule
120
121 //顶层模块的发送40位数据的源文件
122 module uart_tx_data_p(
123 clk,
124 reset_n,
125 data40,
126 trans_go,
127 trans_done,
128 uart_tx
129 );
130 input clk;
131 input reset_n;
132 input [39:0] data40;
133 input trans_go;
134 output reg trans_done;
135 output uart_tx;
136
137 reg [7:0] data;
138 reg send_go;
139 wire tx_done;
140 //首先例化之前的发送八位数据的模块
141 uart_byte_tx uart_byte_tx_inst0(
142 .clk(clk),
143 .reset_n(reset_n),
144 .data(data),
145 .send_go(send_go),
146 .baud_set(4),
147 .uart_tx(uart_tx),
148 .tx_done(tx_done)
149 );
150 reg [2:0]state;
151 always@(posedge clk or negedge reset_n)
152 if(!reset_n)begin
153 state<=0;
154 data<=0;
155 send_go<=0;
156 trans_done<=0;
157 end
158 else if(state==0)begin
159 trans_done<=0;
160 if(trans_go)begin
161 data<=data40[7:0];
162 send_go=1;
163 state<=1;
164 end
165 else begin
166 data<=data;
167 send_go=0;
168 state<=0;
169 end
170 end
171
172 else if(state==1)begin
173 if(tx_done)begin//tx_done用在条件中,且是底层模块的变量
174 data<=data40[15:8];
175 send_go=1;
176 state<=2;
177 end
178 else begin
179 data<=data;
180 send_go=0;
181 state<=1;
182 end
183 end
184
185 else if(state==2)begin
186 if(tx_done)begin//tx_done用在条件中,且是底层模块的变量
187 data<=data40[23:16];
188 send_go=1;
189 state<=3;
190 end
191 else begin
192 data<=data;
193 send_go=0;
194 state<=2;
195 end
196 end
197
198 else if(state==3)begin
199 if(tx_done)begin//tx_done用在条件中,且是底层模块的变量
200 data<=data40[31:24];
201 send_go=1;
202 state<=4;
203 end
204 else begin
205 data<=data;
206 send_go=0;
207 state<=3;
208 end
209 end
210
211 else if(state==4)begin
212 if(tx_done)begin//tx_done用在条件中,且是底层模块的变量
213 data<=data40[39:32];
214 send_go=1;
215 state<=5;
216 end
217 else begin
218 data<=data;
219 send_go=0;
220 state<=4;
221 end
222 end
223
224 else if(state==5)begin
225 if(tx_done)begin//tx_done用在条件中,且是底层模块的变量
226 send_go=0;
227 state<=0;
228 trans_done<=1;
229 end
230 else begin
231 data<=data;
232 send_go=0;
233 state<=5;
234 end
235 end
236 endmodule
237 //顶层仿真文件的改写
238 //`timescale 1ns / 1ps
239 //module uart_tx_data_p2(
240 // clk,
241 // reset_n,
242 // data40,
243 // trans_go,
244 // trans_done,
245 // uart_tx
246 // );
247 // input clk;
248 // input reset_n;
249 // input [39:0] data40;
250 // input trans_go;
251 // output reg trans_done;
252 // output uart_tx;
253 // reg [7:0]data;
254 // reg send_go;
255 // wire tx_done;
256
257 // //例化顶层模块
258 // uart_byte_tx uart_byte_tx_inst0(
259 // .clk(clk),
260 // .reset_n(reset_n),
261 // .data(data),
262 // .send_go(send_go),
263 // .baud_set(4),
264 // .uart_tx(uart_tx),
265 // .tx_done(tx_done)
266 // );
267 // reg [2:0]state;
268 // always@(posedge clk or negedge reset_n)
269 // if(!reset_n)begin
270 // state<=0;
271 // trans_done<=0;
272 // data<=0;
273 // send_go<=0;
274 // end
275
276 // else begin
277 // case(state)
278 // 0:
279 // begin
280 // trans_done<=0;
281 // if(trans_go)begin
282 // data<=data40[7:0];
283 // state<=1;
284 // send_go<=1;
285 // end
286 // else begin
287 // data<=data;
288 // state<=0;
289 // send_go<=0;
290 // end
291 // end
292 // 1:
293 // begin
294 // if(tx_done)begin
295 // data<=data40[15:8];
296 // state<=2;
297 // send_go<=1;
298 // end
299 // else begin
300 // data<=data;
301 // state<=1;
302 // send_go<=0;
303 // end
304 // end
305 // 2:
306 // begin
307 // if(tx_done)begin
308 // data<=data40[23:16];
309 // state<=3;
310 // send_go<=1;
311 // end
312 // else begin
313 // data<=data;
314 // state<=2;
315 // send_go<=0;
316 // end
317 // end
318 // 3:
319 // begin
320 // if(tx_done)begin
321 // data<=data40[31:24];
322 // state<=4;
323 // send_go<=1;
324 // end
325 // else begin
326 // data<=data;
327 // state<=3;
328 // send_go<=0;
329 // end
330 // end
331 // 4:
332 // begin
333 // if(tx_done)begin
334 // data<=data40[39:32];
335 // state<=5;
336 // send_go<=1;
337 // end
338 // else begin
339 // data<=data;
340 // state<=4;
341 // send_go<=0;
342 // end
343 // end
344 // 5:
345 // begin
346 // if(tx_done)begin
347 // state<=0;
348 // send_go<=0;
349 // trans_done<=1;
350 // end
351 // else begin
352 // data<=data;
353 // state<=5;
354 // send_go<=0;
355 // end
356 // end
357 // default:
358 // begin
359 // data<=data;
360 // state<=0;
361 // send_go<=0;
362 // end
363 // endcase
364 // end
365 //endmodule
366 //4、顶层文件的仿真模块
367 `timescale 1ns / 1ps
368 module uart_tx_data_p_tb();
369 reg clk;
370 reg reset_n;
371 reg [39:0] data40;
372 reg trans_go;
373 wire trans_done;
374 wire uart_tx;
375 //这里使用的是该写的模块名
376 uart_tx_data_p2 uart_tx_data_p2_inst0(
377 clk,
378 reset_n,
379 data40,
380 trans_go,
381 trans_done,
382 uart_tx
383 );
384
385 initial clk=1;
386 always#10 clk=!clk;
387
388 initial begin
389 data40=0;
390 trans_go=0;
391 reset_n=0;
392 #201;
393 reset_n=1;
394 #200;
395 data40=40'h123456789a;
396 trans_go=1;
397 #20;
398 @(posedge trans_done)
399 trans_go=0;
400 #200000;
401 data40=40'ha987654321;
402 trans_go=1;
403 #20;
404 @(posedge trans_done)
405 trans_go=0;
406 #2000000;
407 $stop;
408 end
409
410 endmodule