我是靠谱客的博主 结实奇迹,这篇文章主要介绍【verilog】UART串口发送(FPGA)简述核心代码仿真测试,现在分享给大家,希望可以做个参考。

  • 简述
  • 核心代码
  • 仿真测试

简述

串口发送是以一定速率发送单bit数据,通常一组数据为10bit。空闲状态为高电平,起始位为0,中间以低位在前的方式发送8bit数据,终止位为1。
采用计数器 [cnt_baud] 对系统时钟进行计数,计满值即为预设的波特率值 [baud_num]
在这个计数过程中,每当计数值为1时,就产生一个标志值 [flag1]
采用计数器 [cnt_for_flag1] 对flag1进行计数11次,当计数值达到11时,同步清零。
所以cnt_for_flag1 = 11 只能维持1个系统时钟,并不能维持一个baud_num。
能维持一个baud_num的为计数值1~10。利用cnt_for_flag1作为多路器的选择端分别发送出10个bit的数据。
当cnt_for_flag1值为11时,代表一次发送完成,产生done信号。

核心代码

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
module ser_tx(data,en,clk,rst,tx,done); input [7:0] data; input en; input clk; input rst; output reg tx; output reg done; reg [15:0] baud_num = 16'd5207; //5207=9600、2603=19200、1301=38400、867=57600、433=115200 /*将引脚 <input [7:0] data> 进行一级寄存 -> reg_data*/ reg [7:0]reg_data; always@(posedge clk or negedge rst) begin if(!rst) reg_data <= 8'b0; else if(en)begin reg_data <= data; end else reg_data <= data; end /*计数器:0~5207~0~5207....*/ reg [15:0]cnt_baud; always@(posedge clk or negedge rst) begin if(!rst) cnt_baud <= 1'b0; else if(cnt_baud == baud_num) cnt_baud <= 1'b0; else cnt_baud <= cnt_baud + 1'b1; end /*0~5207这个过程中,每当计数到1的时候就产生一个flag*/ reg flag1; always@(posedge clk or negedge rst) begin if(!rst) flag1 <= 1'b0; else if(cnt_baud == 16'd1) flag1 <= 1'b1; else flag1 <= 1'b0; end /*对flag1进行计数,计数11次,但11只能维持1个clk,并不能维持9600bps,然后就被清0*/ reg [3:0] cnt_for_flag1; always@(posedge clk or negedge rst) begin if(!rst) cnt_for_flag1 <= 1'b0; else if(cnt_for_flag1 == 4'd11) cnt_for_flag1 <= 1'b0; else if(flag1 == 1'd1) cnt_for_flag1 <= cnt_for_flag1 + 1'b1; else cnt_for_flag1 <= cnt_for_flag1; end /*依次发送起始位、数据位、终止位*/ always@(posedge clk or negedge rst) begin if(!rst) tx <= 1'd1; //根据时序图,tx的闲时状态是高电平。 else begin case (cnt_for_flag1) 4'd0: tx <= 1'd1; //空闲状态 4'd1: tx <= 1'd0; //起始位 4'd2: tx <= reg_data[0]; //低位在前 4'd3: tx <= reg_data[1]; 4'd4: tx <= reg_data[2]; 4'd5: tx <= reg_data[3]; 4'd6: tx <= reg_data[4]; 4'd7: tx <= reg_data[5]; 4'd8: tx <= reg_data[6]; 4'd9: tx <= reg_data[7]; 4'd10: tx <= 1'd1; //终止位 default:tx <= 1'd1;//空闲状态 endcase end end //每次计数器“cnt_for_flag1”值为11时,代表一次发送完成,产生done信号。 always@(posedge clk or negedge rst) begin if(!rst) done <= 1'd0; else if(cnt_for_flag1 == 4'd11) //cnt_to_10计数到11自动清零 done <= 1'd1; else done <= 1'd0; end endmodule

仿真测试

发送8bit的 data1 = 8’b01001101 作为测试!

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
`timescale 1ns/1ns module ser_tx_tb; reg [7:0] data1; reg en1; reg clk1; reg rst1; wire tx1; wire done1; ser_tx txer ( .data(data1), .en(en1), .clk(clk1), .rst(rst1), .tx(tx1), .done(done1) ); initial clk1 = 1'b1; always#10 clk1 = ~clk1; initial begin rst1 = 1'b0; //未运行状态 #400; rst1 = 1'b1; data1 = 8'b01001101; en1 = 1; #20;//一个时钟周期 en1 = 0; #4000000; $stop; end endmodule

在这里插入图片描述

在这里插入图片描述

最后

以上就是结实奇迹最近收集整理的关于【verilog】UART串口发送(FPGA)简述核心代码仿真测试的全部内容,更多相关【verilog】UART串口发送(FPGA)简述核心代码仿真测试内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(63)

评论列表共有 0 条评论

立即
投稿
返回
顶部