如题,,,再附加上程序的控制说明.......是用GW48教学实验箱仿真的
如果对你有帮助,请大家顶上... 程序直接贴上了 控制说明: 1、电子琴:程序设计采用八个输入端口,分别与实验箱上的按键8~1引脚相连接,采用一个输出端口,与扬声器的引脚连接,时钟频率采用6MHz和4Hz。 按键7~1分别用于中音的七个音符的发音(DO,RE,MI,FA,SO,LA,SI),按键8用于控制乐曲的播放。 程序的编写采用状态机的编写方法,对按键的状态进行判断,对应相应的音符或乐曲。 2、电子钟:程序的设计模块有:时钟初始化模块、时钟工作模块、时钟设置模块、闹钟设置模块、 闰年的月份天数判断模块、数码管显示模块、闹钟铃声模块及其它的设置模块。 程序使用8个输入分别与8个按键连接,用按键8对应时钟工作状态(work_state), 当work_state为0时,时钟正常工作,当work_state为1时,进入时钟设置状态。 按键7对应输入端口display_set控制时钟显示状态(display_state),每按2次(用于产生上升沿触发)则数码管的输出不同。 Display_state与work_state相结合使用,以区分设置的参数。 按键6~4对应输入个脚in_set,该参数共有三位,用以表示三个状态:state_yorh (设置年或小时)、 state_morm(设置月份或分钟)、 state_dors(设置日期或秒钟)。 按键3~2对应数值设置端口up各down。Up用于产生上升沿触发, 当down为0时,则每一个上升沿产生时,相应的参数加1, 当down为1时,则每一个上升沿产生时,相应的参数减1。 按键1与输入端口clock_on相连,用于闹钟的开与关 ,当 clock_on为1时开闹钟,否则关闹钟。扬声器与输出端口speaker相连,用于输出闹钟铃声。
附录:源程序 一、 电子琴: module piano(in,clk_6MHz,clk_4Hz,song,speaker); input in,clk_6MHz,clk_4Hz,song; output speaker; reg speaker; reg[7:0] state; reg song_on; wire[6:0] in;
reg[3:0] high,med,low; reg[13:0] divider,origin; reg[7:0] counter; reg out; wire carry;
reg[20:0] i; parameter zero=8'b0000_0000, one=8'b0000_0001, two=8'b0000_0010, three=8'b0000_0100, four=8'b0000_1000, five=8'b0001_0000, six=8'b0010_0000, seven=8'b0100_0000; initial begin song_on<=0; end
always @(posedge song) begin song_on<=~song_on; end
always @(posedge clk_6MHz)
begin if(song_on) speaker<=out; else begin case(in) zero:begin speaker<=0; i<=0; end one:begin //do if(i>=11451) begin speaker=!speaker; i<=0; end else i<=i+1; end two:begin //re if(i>=10204) begin speaker=!speaker; i<=0; end else i<=i+1; end three:begin //mi if(i>=9091) begin speaker=!speaker; i<=0; end else i<=i+1; end four:begin // fa if(i>=8596) begin speaker=!speaker; i<=0; end else i<=i+1; end five:begin //so if(i>=7653) begin speaker=!speaker; i<=0; end else i<=i+1; end six:begin //lo if(i>=6818) begin speaker=!speaker; i<=0; end else i<=i+1; end seven:begin //si if(i>=6073) begin speaker=!speaker; i<=0; end else i<=i+1; end default:begin speaker<=0; i<=0; end endcase end end
assign carry=(divider==16383); always @(posedge clk_6MHz) begin if(carry) divider<=origin; else divider<=divider+1; end always @(posedge carry) begin out<=~out; //2 分频产生方波信号 end always @(posedge clk_4Hz) begin case({high,med,low}) //分频比预置 'b000000000011: origin<=7281; 'b000000000101: origin<=8730; 'b000000000110: origin<=9565; 'b000000000111: origin<=10310; 'b000000010000: origin<=10647; 'b000000100000: origin<=11272; 'b000000110000: origin<=11831; 'b000001010000: origin<=12556; 'b000001100000: origin<=12974; 'b000100000000: origin<=13516; 'b000000000000: origin<=16383; endcase end always @(posedge clk_4Hz) begin if(counter==63) counter<=0; //计时,以实现循环演奏 else counter<=counter+1; case(counter) //记谱 0: {high,med,low}<='b000000000011; //低音“3” 1: {high,med,low}<='b000000000011; //持续4 个时钟节拍 2: {high,med,low}<='b000000000011; 3: {high,med,low}<='b000000000011; 4: {high,med,low}<='b000000000101; //低音“5” 5: {high,med,low}<='b000000000101; //发3 个时钟节拍 6: {high,med,low}<='b000000000101; 7: {high,med,low}<='b000000000110; //低音“6” 8: {high,med,low}<='b000000010000; //中音“1” 9: {high,med,low}<='b000000010000; //发3 个时钟节拍 10: {high,med,low}<='b000000010000; 11: {high,med,low}<='b000000100000; //中音“2” 12: {high,med,low}<='b000000000110; //低音“6” 13: {high,med,low}<='b000000010000; 14: {high,med,low}<='b000000000101; 15: {high,med,low}<='b000000000101; 16: {high,med,low}<='b000001010000; //中音“5” 17: {high,med,low}<='b000001010000; //发3 个时钟节拍 18: {high,med,low}<='b000001010000; 19: {high,med,low}<='b000100000000; //高音“1” 20: {high,med,low}<='b000001100000; 21: {high,med,low}<='b000001010000; 22: {high,med,low}<='b000000110000; 23: {high,med,low}<='b000001010000; 24: {high,med,low}<='b000000100000; //中音“2” 25: {high,med,low}<='b000000100000; //持续11 个时钟节拍 26: {high,med,low}<='b000000100000; 27: {high,med,low}<='b000000100000; 28: {high,med,low}<='b000000100000; 29: {high,med,low}<='b000000100000; 30: {high,med,low}<='b000000100000; 31: {high,med,low}<='b000000100000; 32: {high,med,low}<='b000000100000; 33: {high,med,low}<='b000000100000; 34: {high,med,low}<='b000000100000; 35: {high,med,low}<='b000000110000; //中音“3” 36: {high,med,low}<='b000000000111; //低音“7” 37: {high,med,low}<='b000000000111; 38: {high,med,low}<='b000000000110; //低音“6” 39: {high,med,low}<='b000000000110; 40: {high,med,low}<='b000000000101; //低音“5” 41: {high,med,low}<='b000000000101; 42: {high,med,low}<='b000000000101; 43: {high,med,low}<='b000000000110; //低音“6” 44: {high,med,low}<='b000000010000; //中音“1” 45: {high,med,low}<='b000000010000; 46: {high,med,low}<='b000000100000; //中音“2” 47: {high,med,low}<='b000000100000; 48: {high,med,low}<='b000000000011; //低音“3” 49: {high,med,low}<='b000000000011; 50: {high,med,low}<='b000000010000; //中音“1” 51: {high,med,low}<='b000000010000; 52: {high,med,low}<='b000000000110; 53: {high,med,low}<='b000000000101; //低音“5” 54: {high,med,low}<='b000000000110; 55: {high,med,low}<='b000000010000; //中音“1” 56: {high,med,low}<='b000000000101; //低音“5” 57: {high,med,low}<='b000000000101; //持续8 个时钟节拍 58: {high,med,low}<='b000000000101; 59: {high,med,low}<='b000000000101; 60: {high,med,low}<='b000000000101; 61: {high,med,low}<='b000000000101; 62: {high,med,low}<='b000000000101; 63: {high,med,low}<='b000000000101; endcase end endmodule
二、电子钟 module clock(work_state,clock_on,clk_6MHz,clk_4Hz,in_set,display_set,clk_1024Hz,up,down,out1,out2,out3, out4,out5,out6,out7,out8,speaker);
input work_state,clk_1024Hz,up,down,display_set,clk_6MHz,in_set,clock_on,clk_4Hz; output out1,out2,out3,out4,out5,out6,out7,out8,speaker; wire[2:0] in_set; reg[3:0] out1,out2,out3,out4,out5,out6,out7,out8; reg[2:0] display_state; reg[7:0] hour,minute,second,year,month,day,day_max; reg[7:0] hour_set,minute_set,second_set,day_set,month_set,year_set,day_set_max; integer century=20; integer i=0; reg speaker;
reg[7:0] clock_hour,clock_minute,clock_second;
reg[3:0] high,med,low; reg[13:0] divider,origin; reg[7:0] counter; reg out; wire carry;
//*****各初始值设置时对应的状态********// parameter state_yorh=3'b100, //设置年或小时对应的按键状态 state_morm=3'b010, //设置月或分对应的按键状态 state_dors=3'b001; //设置日或秒对应的按键状态
//***初始化时钟:08年08月08日00:00:00*****// initial begin year<=8; year_set<=8; month<=8; month_set<=8; day<=8; day_set<=8; hour<=0; minute<=0; second<=0; clock_hour<=0; clock_minute<=0; clock_second<=0; display_state<=0; end
//******电子钟正常工作状态下/work_state等于0时,时钟处于工作状态*******// always @(posedge clk_1024Hz) //频率选择1024HZ begin if(i>=1023) begin i<=0; if(work_state) begin second<=second_set; minute<=minute_set; hour<=hour_set; day<=day_set; month<=month_set; year<=year_set; end else begin if(second>=59) begin second<=0; if(minute>=59) begin minute<=0; if(hour>=23) begin hour<=0; if(day>=day_max) begin day<=1; if(month>=12) begin month<=1; if(year>=99) year<=0; else year<=year+1; end else month<=month+1; end else day<=day+1; end else hour<=hour+1; end else minute<=minute+1; end else second<=second+1; end end else i<=i+1; end
//******数码管显示状态设置*******// always @(posedge display_set) begin if(display_state>=2) display_state<=0; else display_state<=display_state+1; end
//*闹钟模块设置,用clock_on控制闹钟,闹钟铃声播放时间为一分钟,可手动关闭闹钟**// always @(posedge clk_6MHz) begin if(clock_on) begin if(clock_hour==hour&&clock_minute==minute) speaker<=out; else speaker<=0; end else speaker<=0; end
//*************设置时钟的初值*************************// /*用up来触发,当down=0时,一个上升沿触发来时加1,否则减1.***/ always @( posedge up) begin if(!work_state) //时间处于正常工作状态时,使要设置的初始值保持同步 begin second_set<=second; minute_set<=minute; hour_set<=hour; day_set<=day; month_set<=month; year_set<=year; end else begin if(display_state==1)//当display_state==1时,则是设置年月日的初始值,否则是设置时间. begin if(down==0) begin case(in_set) state_yorh:begin if(year_set>=99) year_set<=0; else year_set<=year_set+1; end state_morm:begin if(month_set>=12) month_set<=1; else month_set<=month_set+1; end state_dors:begin if(day_set>=day_set_max) day_set<=1; else day_set<=day_set+1; end endcase end else begin case(in_set)
state_yorh:begin if(year_set<=0) year_set<=99; else year_set<=year_set-1; end state_morm:begin if(month_set<=1) month_set<=12; else month_set<=month_set-1; end state_dors:begin if(day_set<=1) day_set<=day_set_max; else day_set<=day_set-1; end
endcase end end else if(display_state==0) begin if(down==0) begin case(in_set)
state_yorh:begin if(hour_set>=23) hour_set<=0; else hour_set<=hour_set+1; end state_morm:begin if(minute_set>=59) minute_set<=0; else minute_set<=minute_set+1; end state_dors:begin if(second_set>=59) second_set<=0; else second_set<=second_set+1; end
endcase end else begin case(in_set)
state_yorh:begin if(hour_set<=0) hour_set<=23; else hour_set<=hour_set-1; end state_morm:begin if(minute_set<=0) minute_set<=59; else minute_set<=minute_set-1; end state_dors:begin if(second_set<=0) second_set<=59; else second_set<=second_set-1; end
endcase end end else if(display_state==2) begin if(down==0) begin case(in_set)
state_yorh:begin if(clock_hour>=23) clock_hour<=0; else clock_hour<=clock_hour+1; end state_morm:begin if(clock_minute>=59) clock_minute<=0; else clock_minute=clock_minute+1; end state_dors:begin if(clock_second>=59) clock_second<=0; else clock_second<=clock_second+1; end
endcase end else begin case(in_set)
state_yorh:begin if(clock_hour<=0) clock_hour<=23; else clock_hour<=clock_hour-1; end state_morm:begin if(clock_minute<=0) clock_minute<=59; else clock_minute<=clock_minute-1; end state_dors:begin if(clock_second<=0) clock_second<=59; else clock_second<=clock_second-1; end
endcase end
end end end
//**********本年度当前月的天数的计算**********// always @(day or day_set)//当日期变化时,则其所处月份的天数; begin if(month==1||month==3||month==5||month==7||month==8||month==10||month==12) day_max<=31; else if(month==4||month==6||month==9||month==11) day_max<=30; else begin if(({century,year}%400==0)||(({century,year}%4==0)&&({century,year}%10!=0))) day_max<=29; else day_max<=28; end
if(month_set==1||month_set==3||month_set==5||month_set==7||month_set==8||month_set==10||month_set==12) day_set_max<=31; else if(month_set==4||month_set==6||month_set==9||month_set==11) day_set_max<=30; else begin if(({century,year_set}%400==0)||(({century,year_set}%4==0)&&({century,year_set}%10!=0))) day_set_max<=29; else day_set_max<=28; end end
//**********数码管显示模块,display_state=1时,显示年月日,否则显示时间////
always @(posedge clk_6MHz) begin if(!work_state) begin if(display_state==1) begin out8<=year%10; out7<=year/10; out6<=13; out5<=month%10; out4<=month/10; out3<=13; out2<=day%10; out1<=day/10; end else if(display_state==0) begin out8<=hour%10; out7<=hour/10; out6<=15; out5<=minute%10; out4<=minute/10; out3<=15; out2<=second%10; out1<=second/10; end else if(display_state==2) begin out8<=clock_hour%10; out7<=clock_hour/10; out6<=12; out5<=clock_minute%10; out4<=clock_minute/10; out3<=12; out2<=clock_second%10; out1<=clock_second/10; end end else begin if(display_state==1) begin out8<=year_set%10; out7<=year_set/10; out6<=13; out5<=month_set%10; out4<=month_set/10; out3<=13; out2<=day_set%10; out1<=day_set/10; end else if(display_state==0) begin out8<=hour_set%10; out7<=hour_set/10; out6<=15; out5<=minute_set%10; out4<=minute_set/10; out3<=15; out2<=second_set%10; out1<=second_set/10; end else if(display_state==2) begin out8<=clock_hour%10; out7<=clock_hour/10; out6<=12; out5<=clock_minute%10; out4<=clock_minute/10; out3<=12; out2<=clock_second%10; out1<=clock_second/10; end end end
//*******用乐曲《梁祝》作为闹钟铃声*************//
assign carry=(divider==16383); always @(posedge clk_6MHz) begin if(carry) divider<=origin; else divider<=divider+1; end always @(posedge carry) begin out<=~out; //2 分频产生方波信号 end always @(posedge clk_4Hz) begin case({high,med,low}) //分频比预置 'b000000000011: origin<=7281; 'b000000000101: origin<=8730; 'b000000000110: origin<=9565; 'b000000000111: origin<=10310; 'b000000010000: origin<=10647; 'b000000100000: origin<=11272; 'b000000110000: origin<=11831; 'b000001010000: origin<=12556; 'b000001100000: origin<=12974; 'b000100000000: origin<=13516; 'b000000000000: origin<=16383; endcase end always @(posedge clk_4Hz) begin if(counter==63) counter<=0; //计时,以实现循环演奏 else counter<=counter+1; case(counter) //记谱 0: {high,med,low}<='b000000000011; //低音“3” 1: {high,med,low}<='b000000000011; //持续4 个时钟节拍 2: {high,med,low}<='b000000000011; 3: {high,med,low}<='b000000000011; 4: {high,med,low}<='b000000000101; //低音“5” 5: {high,med,low}<='b000000000101; //发3 个时钟节拍 6: {high,med,low}<='b000000000101; 7: {high,med,low}<='b000000000110; //低音“6” 8: {high,med,low}<='b000000010000; //中音“1” 9: {high,med,low}<='b000000010000; //发3 个时钟节拍 10: {high,med,low}<='b000000010000; 11: {high,med,low}<='b000000100000; //中音“2” 12: {high,med,low}<='b000000000110; //低音“6” 13: {high,med,low}<='b000000010000; 14: {high,med,low}<='b000000000101; 15: {high,med,low}<='b000000000101; 16: {high,med,low}<='b000001010000; //中音“5” 17: {high,med,low}<='b000001010000; //发3 个时钟节拍 18: {high,med,low}<='b000001010000; 19: {high,med,low}<='b000100000000; //高音“1” 20: {high,med,low}<='b000001100000; 21: {high,med,low}<='b000001010000; 22: {high,med,low}<='b000000110000; 23: {high,med,low}<='b000001010000; 24: {high,med,low}<='b000000100000; //中音“2” 25: {high,med,low}<='b000000100000; //持续11 个时钟节拍 26: {high,med,low}<='b000000100000; 27: {high,med,low}<='b000000100000; 28: {high,med,low}<='b000000100000; 29: {high,med,low}<='b000000100000; 30: {high,med,low}<='b000000100000; 31: {high,med,low}<='b000000100000; 32: {high,med,low}<='b000000100000; 33: {high,med,low}<='b000000100000; 34: {high,med,low}<='b000000100000; 35: {high,med,low}<='b000000110000; //中音“3” 36: {high,med,low}<='b000000000111; //低音“7” 37: {high,med,low}<='b000000000111; 38: {high,med,low}<='b000000000110; //低音“6” 39: {high,med,low}<='b000000000110; 40: {high,med,low}<='b000000000101; //低音“5” 41: {high,med,low}<='b000000000101; 42: {high,med,low}<='b000000000101; 43: {high,med,low}<='b000000000110; //低音“6” 44: {high,med,low}<='b000000010000; //中音“1” 45: {high,med,low}<='b000000010000; 46: {high,med,low}<='b000000100000; //中音“2” 47: {high,med,low}<='b000000100000; 48: {high,med,low}<='b000000000011; //低音“3” 49: {high,med,low}<='b000000000011; 50: {high,med,low}<='b000000010000; //中音“1” 51: {high,med,low}<='b000000010000; 52: {high,med,low}<='b000000000110; 53: {high,med,low}<='b000000000101; //低音“5” 54: {high,med,low}<='b000000000110; 55: {high,med,low}<='b000000010000; //中音“1” 56: {high,med,low}<='b000000000101; //低音“5” 57: {high,med,low}<='b000000000101; //持续8 个时钟节拍 58: {high,med,low}<='b000000000101; 59: {high,med,low}<='b000000000101; 60: {high,med,low}<='b000000000101; 61: {high,med,low}<='b000000000101; 62: {high,med,low}<='b000000000101; 63: {high,med,low}<='b000000000101; endcase end
endmodule 转载自:http://www.amobbs.com/forum.php?mod=viewthread&tid=1269705 |