1 //还没找到出错的原因
2 //使用串口来控制LED的工作状态
3 //使用串口发送指令到FPGA开发版,来控制第7课中第4个实验的开发版上的LED灯的工作状态。
4 //让LED灯按照指定亮灭模式亮灭,亮灭模式未知,由用户随机指定。8个变换状态为1个循环,每个变化状态的时间值,可以根据不同的应用场景选择。
5 //如何使用串口接收8个字节的数据
6 //顶层模块,例化各个子模块。
7 module uart_rx_ctrl_led(
8 clk,
9 reset_n,
10 led,
11 uart_rx
12 );
13 input clk;
14 input reset_n;
15 output led;
16 input uart_rx;
17 //顶层模块连接模块不需要考虑reg的事情
18 //只有在顶层驱动信号的时候才需要定义reg
19
20 wire [7:0] ctrl;
21 wire [31:0] time_set;
22 wire rx_done;
23 wire [7:0] rx_data;
24 //例化被控制的LED模块
25 counter_led_4 counter_led_4_inst0(
26 .clk(clk),
27 .reset_n(reset_n),
28 .Time(time_set),
29 .ctrl(ctrl),
30 .led(led)
31 );
32 //例化串口接收模块
33 uart_byte_rx uart_byte_rx_inst0(
34 .clk(clk),
35 .reset_n(reset_n),
36 .baud_set(4),
37 .uart_rx(uart_rx),
38 .data(rx_data),
39 .rx_done(rx_done)
40 );
41 //实例化连接两个模块(串口接收模块和LED显示模块)的命令模块。
42 uart_cmd uart_cmd_inst0(
43 .clk(clk),
44 .reset_n(reset_n),
45 .rx_data(rx_data),
46 .rx_done(rx_done),
47 .ctrl(ctrl),
48 .time_set(time_set)
49 );
50 endmodule
51
52 //底层模块一uart_byte_rx
53 //verilog无法实现542.5ns的定时,只能实现540ns,故而tx_done会提前到来。
54 //不过没有关系,可以提前接收,但是不能滞后接收,
55 //如果出现,就会出现丢数据的现象。
56 `timescale 1ns / 1ns
57 module uart_byte_rx(
58 clk,
59 reset_n,
60 baud_set,
61 uart_rx,
62 data,
63 rx_done
64 );
65 input clk;
66 input reset_n;
67 input [2:0] baud_set;
68 input uart_rx;
69 output reg [7:0]data;
70 output reg rx_done;
71 //通过定义两位寄存器来存储发送的状态。为之后的对比形成基础。
72 reg [1:0]uart_rx_r;
73 always@(posedge clk)begin
74 uart_rx_r[0] <= #1 uart_rx;
75 uart_rx_r[1] <= #1 uart_rx_r[0];
76 end
77
78 // wire pedge_uart_rx;
79 // //前一时刻为0,新来的时刻为1,这样才产生了上升沿。
80 //// assign pedge_uart_rx=(uart_rx_r[1] == 0)&&(uart_rx_r[0] == 1);
81 // assign pedge_uart_rx=(uart_rx_r == 2'b01 );
82
83 wire nedge_uart_rx;
84 //前一时刻为1,新来的时刻为0,这样才产生了下降沿。
85 // assign nedge_uart_rx=((uart_rx_r[1]==1)&&(uart_rx_r[0]==0));
86 assign nedge_uart_rx=(uart_rx_r==2'b10);
87 reg[8:0]bps_DR;
88 always@(*)
89 case(baud_set)
90 0:bps_DR = 1000000000/9600/16/20-1;
91 1:bps_DR = 1000000000/19200/16/20-1;
92 2:bps_DR = 1000000000/38400/16/20-1;
93 3:bps_DR = 1000000000/57600/16/20-1;
94 4:bps_DR = 1000000000/115200/16/20-1;
95 default:bps_DR = 1000000000/9600/16/20-1;
96 endcase
97 wire bps_clk_16x;
98 assign bps_clk_16x=(div_cnt == bps_DR/2);
99 //设置发送控制信号rx_en
100 reg rx_en;
101 always@(posedge clk or negedge reset_n)
102 if(!reset_n)
103 rx_en <= #1 0;
104 else if(nedge_uart_rx)
105 rx_en <= #1 1;
106 else if(rx_done || sta_bit >= 4)
107 rx_en <= #1 0;
108 //设置分频计数器的最小单元
109 reg [8:0] div_cnt;
110 always@(posedge clk or negedge reset_n)
111 if(!reset_n)
112 div_cnt <= #1 0;
113 else if(rx_en)begin
114 if(div_cnt == bps_DR)
115 div_cnt <= #1 0;
116 else
117 div_cnt <= #1 div_cnt + 1'b1;
118 end
119 else
120 div_cnt <= #1 0;
121 //采样数据
122 reg [7:0]bps_cnt;
123 always@(posedge clk or negedge reset_n)
124 if(!reset_n)
125 bps_cnt <= #1 0;
126 else if(rx_en)begin
127 if(bps_clk_16x)begin
128 if(bps_cnt == 160)
129 bps_cnt <= #1 0;
130 else
131 bps_cnt <= #1 bps_cnt + 1'b1;;
132 end
133 else
134 bps_cnt <= #1 bps_cnt;
135 end
136 else
137 bps_cnt <= #1 0;
138 //接收数据
139 //二位数组reg width name number;
140 reg [7:0] r_data [7:0];
141 reg [2:0] sta_bit;
142 reg [2:0] sto_bit;
143
144 always@(posedge clk or negedge reset_n)
145 if(!reset_n)begin
146 sta_bit <= #1 0;
147 sto_bit <= #1 0;
148 r_data[0] <= #1 0;
149 r_data[1] <= #1 0;
150 r_data[2] <= #1 0;
151 r_data[3] <= #1 0;
152 r_data[4] <= #1 0;
153 r_data[5] <= #1 0;
154 r_data[6] <= #1 0;
155 r_data[7] <= #1 0;
156 end
157 else if (bps_clk_16x)begin
158 case(bps_cnt)
159 0:begin
160 sta_bit <= #1 0;
161 sto_bit <= #1 0;
162 r_data[0] <= #1 0;
163 r_data[1] <= #1 0;
164 r_data[2] <= #1 0;
165 r_data[3] <= #1 0;
166 r_data[4] <= #1 0;
167 r_data[5] <= #1 0;
168 r_data[6] <= #1 0;
169 r_data[7] <= #1 0;
170 end
171 5,6,7,8,9,10,11:sta_bit <= #1 sta_bit + uart_rx;
172 21,22,23,24,25,26,27: r_data[0] <= #1 r_data[0] + uart_rx;
173 37,38,39,40,41,42,43: r_data[1] <= #1 r_data[1] + uart_rx;
174 53,54,55,56,57,58,59: r_data[2] <= #1 r_data[2] + uart_rx;
175 69,70,71,72,73,74,75: r_data[3] <= #1 r_data[3] + uart_rx;
176 85,86,87,88,89,90,91: r_data[4] <= #1 r_data[4] + uart_rx;
177 101,102,103,104,105,106,107:r_data[5] <= #1 r_data[5] + uart_rx;
178 117,118,119,120,121,122,123:r_data[6] <= #1 r_data[6] + uart_rx;
179 133,134,135,136,137,138,139:r_data[7] <= #1 r_data[7] + uart_rx;
180 149,150,151,152,153,154,155:sto_bit <= #1 sto_bit + uart_rx;
181 default:;
182 endcase
183 end
184 always@(posedge clk or negedge reset_n)
185 if(!reset_n)begin
186 data<= #1 0;
187 end
188 else if(bps_clk_16x && bps_cnt==159)begin
189 data[0] <= #1 (r_data[0] >= 4) ? 1:0;
190 data[1] <= #1 (r_data[1] >= 4) ? 1:0;
191 data[2] <= #1 (r_data[2] >= 4) ? 1:0;
192 data[3] <= #1 (r_data[3] >= 4) ? 1:0;
193 data[4] <= #1 (r_data[4] >= 4) ? 1:0;
194 data[5] <= #1 (r_data[5] >= 4) ? 1:0;
195 data[6] <= #1 (r_data[6] >= 4) ? 1:0;
196 data[7] <= #1 (r_data[7] >= 4) ? 1:0;
197 end
198 always@(posedge clk or negedge reset_n)
199 if(!reset_n)
200 rx_done<= #1 0;
201 else if((div_cnt == bps_DR/2) && bps_cnt == 160)
202 rx_done <= #1 1;
203 else
204 rx_done <= #1 0;
205 endmodule
206
207 //底层模块二uart_cmd
208
209 `timescale 1ns / 1ns
210 module uart_cmd(
211 clk,
212 reset_n,
213 rx_data,
214 rx_done,
215 ctrl,
216 time_set
217 );
218 input clk;
219 input reset_n;
220 input [7:0] rx_data;
221 input rx_done;
222 output reg [7:0] ctrl;
223 output reg[31:0] time_set;
224
225 reg [7:0] data_str [7:0];
226 always@(posedge clk)
227 //循环移位接收数据,每来一次rx_done,接收一次数据。
228 if(rx_done)begin
229 data_str[7] <= #1 rx_data;
230 data_str[6] <= #1 data_str[7];
231 data_str[5] <= #1 data_str[6];
232 data_str[4] <= #1 data_str[5];
233 data_str[3] <= #1 data_str[4];
234 data_str[2] <= #1 data_str[3];
235 data_str[1] <= #1 data_str[2];
236 data_str[0] <= #1 data_str[1];
237 end
238 //判断每位数据是否是所发送的8比特数据,
239 //判断M0,M1,M7是否如自定义的数据一样。
240 reg r_rx_done;
241 always@(posedge clk)
242 r_rx_done <= rx_done;
243
244
245 always@(posedge clk or negedge reset_n)
246 if(!reset_n)begin
247 ctrl <= #1 0;
248 time_set <= #1 0;
249 end
250 else if(r_rx_done)begin
251 if((data_str[0]==8'h55) && (data_str[1]==8'hA5) && (data_str[7]==8'hF0))begin
252 time_set[7:0] <= #1 data_str[2];
253 time_set[15:8] <= #1 data_str[3];
254 time_set[23:16] <= #1 data_str[4];
255 time_set[31:24] <= #1 data_str[5];
256 ctrl <= #1 data_str[6];
257 end
258
259 end
260 endmodule
261
262 //底层模块三counter_led_4
263
264 //可能是led出现了问题
265 `timescale 1ns / 1ns
266 module counter_led_4(
267 clk,
268 reset_n,
269 Time,
270 ctrl,
271 led
272 );
273 input clk;
274 input reset_n;
275 input [31:0] Time;
276 input [7:0] ctrl;
277 output reg led;
278 reg [31:0] counter;
279 always@(posedge clk or negedge reset_n)
280 if(!reset_n)
281 counter <= #1 0;
282 //波形出现Time=0的情况,上电的时候,counter==0-1发现不满足
283 //,就一直自加,直到加到32'hFFFF FFFF.
284 //前面接收发送数据用的时间过长,导致Time值大于25000000,直到
285 //32位计数满了之后才继续进行。
286 else if(counter >= Time-1)
287 counter <= #1 0;
288 else
289 counter <= #1 counter + 1'b1;
290 reg [2:0] counter2;
291 always@(posedge clk or negedge reset_n)
292 if(!reset_n)
293 counter2 <= #1 0;
294 else if(counter == Time-1)//一旦超过范围值就清零
295 counter2 <= #1 counter2 + 1'b1;
296
297 always@(posedge clk or negedge reset_n)
298 if(!reset_n)
299 led <= #1 0;
300 else case(counter2)
301 0:led <= #1 ctrl[0];
302 1:led <= #1 ctrl[1];
303 2:led <= #1 ctrl[2];
304 3:led <= #1 ctrl[3];
305 4:led <= #1 ctrl[4];
306 5:led <= #1 ctrl[5];
307 6:led <= #1 ctrl[6];
308 7:led <= #1 ctrl[7];
309 default:led <= #1 led;
310 endcase
311 endmodule
312
313
314 //仿真文件
315 `timescale 1ns / 1ps
316 module uart_rx_ctrl_led_tb();
317 reg clk;
318 reg reset_n;
319 wire led;
320 reg uart_rx;
321 uart_rx_ctrl_led uart_rx_ctrl_led_inst0(
322 .clk(clk),
323 .reset_n(reset_n),
324 .led(led),
325 .uart_rx(uart_rx)
326 );
327
328 initial clk = 1;
329 always#10 clk = !clk;
330
331 initial begin
332 reset_n = 0;
333 uart_rx = 1;
334 #201;
335 reset_n = 1;
336 #200;
337 uart_tx_byte(8'h55);
338 // @(posedge rx_done);
339 #90000;
340 uart_tx_byte(8'ha5);
341 // @(posedge rx_done);
342 #90000;
343 uart_tx_byte(8'h40);
344 #90000;
345 uart_tx_byte(8'h78);
346 #90000;
347 uart_tx_byte(8'h7D);
348 #90000;
349 uart_tx_byte(8'h01);
350 #90000;
351 uart_tx_byte(8'hAA);
352 #90000;
353 uart_tx_byte(8'hF0);
354 #90000;
355
356
357
358 uart_tx_byte(8'h55);
359 // @(posedge rx_done);
360 #90000;
361 uart_tx_byte(8'ha5);
362 // @(posedge rx_done);
363 #90000;
364 uart_tx_byte(8'h9a);
365 #90000;
366 uart_tx_byte(8'h78);
367 #90000;
368 uart_tx_byte(8'h56);
369 #90000;
370 uart_tx_byte(8'h34);
371 #90000;
372 uart_tx_byte(8'h12);
373 #90000;
374 uart_tx_byte(8'hf1);
375 #90000;
376 $stop;
377 end
378
379 //新语法
380 task uart_tx_byte;
381 input [7:0]tx_data;
382 begin
383 uart_rx = 1;
384 #20;
385 uart_rx = 0;
386 #8680;
387 uart_rx = tx_data[0];
388 #8680;
389 uart_rx = tx_data[1];
390 #8680;
391 uart_rx = tx_data[2];
392 #8680;
393 uart_rx = tx_data[3];
394 #8680;
395 uart_rx = tx_data[4];
396 #8680;
397 uart_rx = tx_data[5];
398 #8680;
399 uart_rx = tx_data[6];
400 #8680;
401 uart_rx = tx_data[7];
402 #8680;
403 uart_rx=1;
404 #8680;
405 end
406 endtask
407
408 endmodule
2023-03-27 22:17:29