1、实 验报告2016 年 5 月 24目录一、 实验题目 3学 院: 大数据与信息工程学院专 业: 电 子 与 通 信 工 程学 号: 2015021718学生姓名: 杨 鹏 举指导教师: 李 良 荣二、 实验目的 3三、 实验要求 3四、 洗衣机工作原理与功能说明 3状态图如下 4程序 RTL 视图如下 4五、详细代码如下 5模块一实现洗衣机状态转换和各状态输出控制 5模块二实现复位信号的异步复位同步释放 11模块三实现当前状态的数码管显示 12模块四实现按键检测 13模块五实现顶层的调用 15一、 实验题目自动洗衣机设计二、 实验目的1、熟练掌握 Quartus II 工程文件的建立过程。2
2、、掌握 Verilog 的基本语法、语句、模块的使用。3、了解模块的建立与使用。4、了解 FPGA 的开发基本流程。三、 实验要求1、初始状态,准备启动。2、开始进水;为防止进水过程出现故障,故不用定时器控制,而是手动给一个信号模拟水位检测传感器,表示进水完成。3、开始洗涤:正反洗涤 4 次开始排水。4、排水后立即脱水。5、洗涤之后漂洗 2 次,每次漂洗过后都排水甩干。6、整个过程全部用数码管来显示状态机状态,并用两个led 灯表示电机的正转与反转状态。四、 洗衣机工作原理与功能说明自动洗衣机的工作原理:洗衣机有 7 个工作状态分别为空闲(idle) 、加水( water) 、洗衣(wash)
3、 、排水(drain) 、甩干(dry) 、漂洗(rinse ) 、结束音乐提示(music) 。一次完整的洗涤,进水 3 次、洗涤 1 次、漂洗两次、排水 3 次、甩干 3 次。一次完整的状态转换为:空闲(idle) 、加水(water) 、洗衣(wash) 、排水(drain) 、甩干(dry) 、加水(water) 、漂洗(rinse) 、排水(drain) 、甩干(dry) 、加水(water) 、漂洗(rinse) 、排水(drain) 、甩干(dry) 、结束音乐提示(music) 。程序功能说明:程序有 4 个输入 start 启动信号、water_test水满检测信号,水满了就
4、置一、drain_test 排水检测,水排完了就置一、emergency 紧急停止信号,任何情况下输入都进入 idle 状态,即停止工作。一开上电过后系统处于空闲状态,当输入信号 start 后进入加水状态,水满过后进入浸泡状态,浸泡完毕进入洗衣状态,洗衣完毕进入排水状态,第一次排水完毕进入甩干状态,第一次甩干完成进入加水状态,第二次加水完成后进入第一次漂洗状态,第一次漂洗完毕进入第二次排水状态,排水完毕进入第二次甩干状态,第二次甩干完毕进入第三次加水状态,再进入第二次漂洗状态,第三次排水状态,第三次甩干状态,进入结束音乐提醒状态,回到空闲状态。洗衣服和漂洗为洗衣电机的低速档位,在排水过程中将
5、电机档位变为高档位。当甩干完毕变到其他状态时,就把电机档位变到低档位。洗涤和漂洗时,电机正转和反转之间有 3 秒钟的延时(即让电机自动减速,不至于电机突然反转时负荷太大烧毁电机) 。状态图如下程序 RTL 视图如下4 个输入由外部按键输入,经过模块 key 按键消抖确定按键是否被按下。按键输入到模块 washer 作为一些状态转换的条件。washer 的状态输出到数码管显示模块 segmain 显示系统当前处于什么状态。系统有 4 个输出 clockwise 正转信号 0 表示转,1 表示不转、anticlockwise 反转信号 0 表示转,1 表示不转、finish 结束信号 0 表示结束
6、,1 表示未结束、cstate 表示当前状态。经调试实现了想要的功能。五、详细代码如下模块一实现洗衣机状态转换和各状态输出控制/-/用 1 段式状态机,分成 3 段来写/-module washer(clk,rst_n,start,water_test, /水满信号drain_test, /排水检测emergency, /紧急情况处理clockwise, /正转信号anticlockwise, /反转信号finish, /结束信号level, /档位显示 0 为高档位 1 为低档位cstate /用于显示处于哪个状态);parameter idle = 0,inwater = 1,steep
7、= 2, /浸泡wash = 3, /洗涤drain = 4, /排水dry = 5,rinse = 6, /漂洗music = 7;reg steep_test; /浸泡结束信号reg wash_test; /洗涤结束信号reg dry_test; /甩干结束信号reg rinse_test; /漂洗结束信号reg music_test; /音乐结束信号input clk,rst_n; /时钟 复位input start; /启动信号input water_test; /水满信号input drain_test; /排水检测input emergency; /紧急停止信号output reg
8、 clockwise; /正转信号 0 表示转,1 表示不转output reg anticlockwise; /反转信号 0 表示转,1 表示不转output reg finish; /结束信号 0 表示结束, 1 表示未结束output 2:0 cstate; /表示现在的状态output reg level; /显示电机档位reg2:0 cstate_r;assign cstate = cstate_r;reg1:0 water_time; /洗涤一次 漂洗两次reg1:0 drain_time; /排水三次reg1:0 dry_time; /甩干三次always(posedge clk
9、)if(rst_n)begincstate_r = idle;endelsebegincase(cstate_r)idle: if(start) begin /0cstate_r = inwater; /一开始就进入进水状态endelse cstate_r = idle;/1inwater:if(emergency) cstate_r = idle; /遇到紧急情况就停止else if(water_test)begincase(water_time)2b00: cstate_r = steep; /水满了就进入浸泡状态2b01: cstate_r = rinse; 2b10: cstate_r
10、 = rinse;default: ;endcaseendelse cstate_r = inwater;/2steep:if(emergency) cstate_r = idle; /遇到紧急情况就停止else if(steep_test) cstate_r = wash; /浸泡完毕就进入洗涤状态else cstate_r = steep;/3wash:if(emergency) cstate_r = idle; /遇到紧急情况就停止else if(wash_test) cstate_r = drain; /洗完就进入排水状态else cstate_r = wash;/4drain:if(
11、emergency) cstate_r = idle;else if(drain_test) begincstate_r = dry;endelse cstate_r = drain;/5dry:if(emergency) cstate_r = idle;else if(dry_test) begincase(dry_time)2b01: cstate_r = inwater;2b10: cstate_r = inwater;2b11: cstate_r = music;default: ;endcaseendelse cstate_r = dry;/6 rinse:if(emergency)
12、 cstate_r = idle;else if(rinse_test) cstate_r = drain;else cstate_r = rinse;/7music:if(emergency) cstate_r = idle;else if(music_test) cstate_r = idle;else cstate_r = music;default: cstate_r = idle;endcaseendreg28:0 counter;reg3:0 num;/reg in_water;always(posedge clk or negedge rst_n)beginif(rst_n)be
13、ginsteep_test = 1b0;wash_test = 1b0;dry_test = 1b0;rinse_test = 1b0;music_test = 1b0;water_time =2d0;drain_time = 2d0;dry_time = 2d0;counter = 29d0;num = 4d0;music_test = 1b0;clockwise = 1b1;anticlockwise = 1b1;finish = 1b1;endelse begincase(cstate_r)idle: begin /0music_test = 1b0; /音乐结束信号复位clockwis
14、e = 1b1;anticlockwise = 1b1; /电机旋转方向信号finish = 1b1; /结束信号wash_test = 1b0; /洗涤完成信号复位rinse_test = 1b0;dry_test = 1b0; /将甩干标志清零steep_test = 1b0; /将浸泡结束标志位复位music_test = 1b0;endinwater: begin /1 water_test 不用置零clockwise = 1b1;anticlockwise = 1b1;level = 1b1; /档位跳到低位档dry_test = 1b0; /将甩干标志清零if(water_test
15、)begin /进水完成信号为外部输入信号if(water_time = 2b11)beginwater_time = 2b00;endelse water_time = water_time + 1b1;endendsteep: begin /2clockwise = 1b1;anticlockwise = 1b1;if(counter = 29d250000000) begincounter = 29d0;steep_test = 1b1; /浸泡 10 秒钟浸泡完成endelse counter = counter + 1b1;endwash: begin /3steep_test =
16、1b0; /将浸泡结束标志位复位case(num)4d0: beginclockwise = 1b0; /正转 5 秒anticlockwise = 1b1;end4d1: beginclockwise = 1b1; /停转 3 秒anticlockwise = 1b1;end4d2: beginclockwise = 1b1; /反转 5 秒anticlockwise = 1b0;end4d3: beginclockwise = 1b1; /停转 3 秒anticlockwise = 1b1;end4d4: beginclockwise = 1b0; /正转 5 秒anticlockwise
17、 = 1b1;end4d5: beginclockwise = 1b1; /停转 3 秒anticlockwise = 1b1;end4d6: beginclockwise = 1b1; /反转 5 秒anticlockwise = 1b0;end4d7: beginnum = 4d0;wash_test = 1b1; /下一个状态置零clockwise = 1b1;anticlockwise = 1b1;enddefault: begin clockwise = 1b1;anticlockwise = 1b1;endendcaseif(num = 1 | num = 3 | num = 5)
18、beginif(counter = 29d150000000) /延时 3 秒begincounter = 29d0;num = num + 1b1;endelse counter = counter + 1b1;endelse if(counter = 29d250000000) begincounter = 29d0;num = num + 1b1;endelse counter = counter + 1b1;enddrain:begin /4 drain_test 不用置零clockwise = 1b1;anticlockwise = 1b1;wash_test = 1b0; /洗涤完
19、成信号复位rinse_test = 1b0; /漂洗完成信号复位level = 1b0; /调节档位到高档位if(drain_test)begin /排水信号为外部输入信号if(drain_time = 2b11)begin /排水 3 次drain_time = 2b00;endelse drain_time = drain_time + 1b1;endenddry: begin /5clockwise = 1b0; /甩干正转信号置 1anticlockwise = 1b1;if(counter = 29d250000000) begincounter = 29d0;clockwise =
20、 1b1; /停止正转anticlockwise = 1b1;dry_test = 1b1; /甩干完成 未清零所以一次跳两个状态if(dry_time = 2b11)begindry_time = 2b00;endelse dry_time = dry_time + 1b1;endelse counter = counter + 1b1;endrinse: begin /6case(num)4d0:beginclockwise = 1b0; /正转 5 秒anticlockwise = 1b1;end4d1:beginclockwise = 1b1; /停止转动 3 秒anticlockwi
21、se = 1b1;end4d2:beginclockwise = 1b1; /反转 5 秒anticlockwise = 1b0;end4d3:beginrinse_test = 1b1;num = 3d0;clockwise = 1b1; /停止转动anticlockwise = 1b1;enddefault:;endcaseif(num = 1)beginif(counter = 29d150000000) /延时 3 秒begincounter = 29d0;num = num + 1b1;endelse counter = counter +1;endelse if(counter =
22、 29d250000000)begin /延时 5 秒counter = 29d0;num = num + 1b1;endelse counter = counter + 1b1;endmusic: begin /7clockwise = 1b1;anticlockwise = 1b1;level = 1b1; /将档位调到低档位dry_test = 1b0; /将甩干完成信号复位finish = 1b0; /结束将结束信号置 1if(counter = 29d50000000) begincounter = 29d0;music_test = 1b1;end else counter = c
23、ounter + 1b1;enddefault: ;endcaseendendendmodule模块三实现当前状态的数码管显示module segmain(clk,rst_n,datain,seg_data,seg_com);input clk;input rst_n;input2:0datain;output7:0seg_data;output seg_com;reg7:0seg_data;reg2:0bcd_led;reg18:0count;assign seg_com = 1b0;always(posedge clk)beginif(rst_n)begincount = 19d0;end
24、elsecount = count + 1b1;endalways(posedge clk)beginif(count18)beginbcd_led = datain;endendalways(bcd_led)begincase(bcd_led)4h0:seg_data = 8hc0; /0 共阳低有效4h1:seg_data = 8hf9; /14h2:seg_data = 8ha4; /24h3:seg_data = 8hb0; /34h4:seg_data = 8h99; /44h5:seg_data = 8h92; /54h6:seg_data = 8h82; /64h7:seg_da
25、ta = 8hf8; /7/4h8:seg_data = 8h80; /8/4h9:seg_data = 8h90; /9/4ha:seg_data = 8h88; /A/4hb:seg_data = 8h83; /B/4hc:seg_data = 8hc6; /C/4hd:seg_data = 8ha1; /D/4he:seg_data = 8h86; /E/4hf:seg_data = 8h8e; /Fdefault:seg_data = 8hc0; /0endcaseendendmodule模块四实现按键检测module key(clk,rst_n,sw,start,water_test
26、,drain_test,emergency);input clk; /主时钟信号,50MHzinput rst_n; /复位信号,低有效input3:0 sw; /三个独立按键,低表示按下output reg start; /启动信号output reg water_test; /水满信号output reg drain_test; /排水检测output reg emergency; /紧急停止信号 /-reg3:0 key_rst; always (posedge clk or negedge rst_n)if (!rst_n) key_rst = 3b111;else key_rst =
27、 sw;/将按键状态存入寄存器中reg3:0 key_rst_r; /每个时钟周期的上升沿将 low_sw 信号锁存到low_sw_r 中always ( posedge clk or negedge rst_n )if (!rst_n) key_rst_r = 4b1111;else key_rst_r = key_rst; /寄存器中存入按键上个时钟周期的按键状态/当寄存器 key_rst 由 1 变为 0 时,led_an 的值变为高,维持一个时钟周期 wire3:0 key_an = key_rst_r /-reg19:0 cnt; /计数寄存器always (posedge clk
28、or negedge rst_n)if (!rst_n) cnt = 20d0; /异步复位else if(key_an) cnt =20d0; /检测到有键被按下(可能是按键抖动直到检测不到)else cnt = cnt + 1b1; /就将计数器清零reg3:0 low_sw;always (posedge clk or negedge rst_n)if (!rst_n) low_sw = 4b1111;else if (cnt = 20hfffff) /满 20ms,将按键值锁存到寄存器 low_sw 中 cnt = 20hffffflow_sw = sw;/-reg 3:0 low_s
29、w_r; /每个时钟周期的上升沿将 low_sw 信号锁存到low_sw_r 中always ( posedge clk or negedge rst_n )if (!rst_n) low_sw_r = 4b1111;else low_sw_r = low_sw;wire3:0 led_ctrl = low_sw_r3:0 always (posedge clk or negedge rst_n)if (!rst_n) beginstart = 1b0; /启动信号water_test = 1b0; /水满信号drain_test = 1b0; /排水检测emergency = 1b0; /紧
30、急信号endelse beginif ( led_ctrl0 ) start = 1b1;else start = 1b0;if ( led_ctrl1 ) water_test = 1b1;else water_test = 1b0;if ( led_ctrl2 ) drain_test = 1b1;else drain_test = 1b0;if ( led_ctrl3 ) emergency = 1b1;else emergency = 1b0;endendmodule模块五实现顶层的调用module washer_top(input clk,rst_n,start,water_test
31、, /水满信号drain_test, /排水检测emergency, /紧急情况处理output clockwise, /正转信号anticlockwise, /反转信号finish, /结束信号level,output7:0seg_data,output seg_com);wire sys_rst_n;wire start1;wire water_test1;wire drain_test1;wire emergency1;wire2:0 cstate;washer washer(.clk(clk),.rst_n(sys_rst_n),.start(start1),.water_test(w
32、ater_test1), /水满信号.drain_test(drain_test1), /排水检测.emergency(emergency1), /紧急情况处理.clockwise(clockwise), /正转信号.anticlockwise(anticlockwise),/反转信号.finish(finish), /结束信号.cstate(cstate);synchronism_design syschronism(.clk(clk),.rst_n(rst_n),.sys_rst_n(sys_rst_n);segmain segmain(.clk(clk),.rst_n(sys_rst_n),.datain(cstate),.seg_data(seg_data),.seg_com(seg_com);key key(.clk(clk),.rst_n(sys_rst_n),.sw(emergency,start,water_test,drain_test),.start(start1),.water_test(water_test1),.drain_test(drain_test1),.emergency(emergency1);endmodule