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

 

posted on 2023-03-09 15:42  无情的造轮子  阅读(268)  评论(0编辑  收藏  举报