1 //1、底层代码源代码发送10位数据
2 module uart_pr(
3 clk,
4 reset_n,
5 send_go,
6 data,
7 baud_set,
8 tx_done,
9 uart_tx
10 );
11 input clk;
12 input reset_n;
13 input send_go;
14 input [7:0]data;
15 input [2:0]baud_set;
16 output reg tx_done;
17 output reg uart_tx;
18
19
20 //再书写关于bps_DR的选择计算
21 reg [17:0] bps_DR;
22 always@(*)
23 case(baud_set)
24 0:bps_DR=50000000/9600;
25 1:bps_DR=50000000/19200;
26 2:bps_DR=50000000/38400;
27 3:bps_DR=50000000/57600;
28 4:bps_DR=50000000/115200;
29 default:bps_DR=50000000/9600;
30 endcase
31 reg send_en;
32 always@(posedge clk or negedge reset_n)
33 if(!reset_n)
34 send_en<=0;
35 else if(send_go)//记住这边只能用顶层的计数counter,不能用底层的div_cnt以及bps_cnt;
36 send_en<=1;
37 else if(tx_done)
38 send_en<=0;
39
40 //存储数据
41 reg [7:0]r_data;
42 always@(posedge clk or negedge reset_n)//这里为什么不需要复位的下降沿
43 if(!reset_n)
44 r_data<=0;
45 else if(send_go)
46 r_data<=data;
47 else
48 r_data<=r_data;
49 //首先书写对应波特率的计数,分频div_cnt
50 //根据最低的波特率来确定div_cnt的宽度
51 reg [17:0]div_cnt;
52 always@(posedge clk or negedge reset_n)
53 if(!reset_n)
54 div_cnt<=0;
55 else if(send_en)begin
56 if(div_cnt==bps_DR-1)
57 div_cnt<=0;
58 else
59 div_cnt<=div_cnt+1'b1;
60 end
61 else
62 div_cnt<=0;
63
64 wire bps_clk;
65 assign bps_clk=(div_cnt==1);
66 //开始书写下一个计数bps_cnt,来实现10为数据的发送
67 reg [3:0] bps_cnt;
68 always@(posedge clk or negedge reset_n)
69 if(!reset_n)
70 bps_cnt<=0;
71 else if(send_en)begin
72 if(bps_clk)begin
73 if(bps_cnt==11)
74 bps_cnt<=0;
75 else
76 bps_cnt<=bps_cnt+1'b1;
77 end
78 end
79 else
80 bps_cnt=0;
81 //开始书写发送10位的数据
82 always@(posedge clk or negedge reset_n)
83 if(!reset_n)
84 uart_tx<=1;
85 else case(bps_cnt)
86 1:uart_tx<=0;
87 2:uart_tx<=r_data[0];
88 3:uart_tx<=r_data[1];
89 4:uart_tx<=r_data[2];
90 5:uart_tx<=r_data[3];
91 6:uart_tx<=r_data[4];
92 7:uart_tx<=r_data[5];
93 8:uart_tx<=r_data[6];
94 9:uart_tx<=r_data[7];
95 10:uart_tx<=1;
96 11:uart_tx<=1;
97 default:uart_tx<=1;
98 endcase
99
100 always@(posedge clk or negedge reset_n)
101 if(!reset_n)
102 tx_done<=0;
103 else if((bps_cnt==10)&&(bps_clk==1))
104 tx_done<=1;
105 else
106 tx_done<=0;
107 endmodule
108 //2、底层代码仿真文件
109 `timescale 1ns / 1ps
110 module uart_pr_tb();
111 reg clk;
112 reg reset_n;
113 reg send_en;
114 reg [7:0]data;
115 reg [2:0]baud_set;
116 wire tx_done;
117 wire uart_tx;
118 uart_pr uart_pr_tb(
119 .clk(clk),
120 .reset_n(reset_n),
121 .send_en(send_en),
122 .data(data),
123 .baud_set(baud_set),
124 .tx_done(tx_done),
125 .uart_tx(uart_tx)
126 );
127 initial clk=1;
128 always#10 clk=!clk;
129
130 initial begin
131 reset_n=0;
132 data=0;
133 send_en=0;
134 baud_set=4;
135 #201;
136 reset_n=1;
137 #20;
138 data=8'h57;
139 send_en=1;
140 @(posedge tx_done)
141 send_en=0;
142 #2000;
143 data=8'h75;
144 send_en=1;
145 @(posedge tx_done)
146 send_en=0;
147 #20000;
148 $stop;
149 end
150
151
152 endmodule
153 3、顶层代码源文件
154 //每10ms以115200的波特率发送一个数据,每次发送的
155 //数据比前一个数据大一(计数器)
156 //顶层设计模块
157 module uart_test1(
158 clk,
159 reset_n,
160 uart_tx
161 );
162 input clk;
163 input reset_n;
164 output uart_tx;
165
166 reg send_go;//这是顶层的send_en放在下面会出错
167 reg [7:0] data;
168 //先将发送10位数据的uart进行例化
169 uart_pr uart_pr_inst0(
170 .clk(clk),
171 .reset_n(reset_n),
172 .send_go(send_go),
173 .data(data),
174 .baud_set(3'd4),
175 .tx_done(tx_done),
176 .uart_tx(uart_tx)
177 );
178 //先写出一个10ms的计数器
179 reg [18:0]counter;
180 always@(posedge clk or negedge reset_n)
181 if(!reset_n)
182 counter<=0;
183 else if(counter==499999)
184 counter<=0;
185 else
186 counter<=counter+1'b1;
187 //书写发送信号send_en
188 //底层不是控制过send_en了吗??怎么这里还写控制send_en
189 //因为底层控制send_en在testbench中控制的,最后不会在板级验证的时候起作用
190 //那只在testbench中也就是仿真波形中会出现。
191 always@(posedge clk or negedge reset_n)
192 if(!reset_n)
193 send_go<=0;
194 else if(counter==1)//记住这边只能用顶层的计数counter,不能用底层的div_cnt以及bps_cnt;
195 send_go<=1;
196 else //设置send_go的时候一定要注意,什么时候开始,什么时候结束要形成闭环。
197 send_go<=0;//else还是要加,只不过不用带tx_done因为tx_done已经在顶层模块说明过了
198 //书写data的每次加1;
199 always@(posedge clk or negedge reset_n)
200 if(!reset_n)
201 data<=0;
202 else if(tx_done)
203 data<=data+1'b1;
204 endmodule
205 4、顶层代码仿真文件
206 `timescale 1ns / 1ps
207 module uart_test1_tb();
208 reg clk;
209 reg reset_n;
210 wire uart_tx;
211 uart_test1 uart_test1_inst0(
212 .clk(clk),
213 .reset_n(reset_n),
214 .uart_tx(uart_tx)
215 );
216
217 initial clk=1;
218 always #10 clk=!clk;
219
220 initial begin
221 reset_n=0;
222 #201;
223 reset_n=1;
224
225 #50000000;
226 $stop;
227
228 end
229 endmodule