assign key = {key1,key2,key3,key4,key5,key6,key7,key8,key9}; //由按键拼键为变量key //调用子调块 digital_piano
m1(.inclk(inclk),.key1(key1),.key2(key2),.key3(key3),.key4(key4),
.key5(key5),.key6(key6),.key7(key7),.beep2(out2),.num(num)); bell m2(.inclk(inclk),.beep1(out1)); bell2 m3(.inclk(inclk),.beep3(out3)); bell3 m4(.inclk(inclk),.beep4(out4));
always @(num) begin
if(num==3'd1)
shumaguan<={4'b1110,1'b1,led7(1)}; else if(num==4'd2)
shumaguan<={4'b1110,1'b1,led7(2)}; else if(num==4'd3)
shumaguan<={4'b1110,1'b1,led7(3)}; else if(num==4'd4)
shumaguan<={4'b1110,1'b1,led7(4)}; else if(num==4'd5)
shumaguan<={4'b1110,1'b1,led7(5)}; else if(num==4'd6)
shumaguan<={4'b1110,1'b1,led7(6)}; else if(num==4'd7)
shumaguan<={4'b1110,1'b1,led7(7)}; end
always @(posedge clk_6M) //在时钟的上升沿检测是否有按键按下 begin
if(key == 9'b111111110) mm <= 2'b01;
else if(key==9'b111111101) mm <= 2'b10;
else if(key==9'b111111100) mm <= 2'b11; else mm <= 2'b00; end
always@(posedge inclk) begin
if(c<4'd4)
19
c<=c+4'd1; else begin c<=4'd0;
clk_6M=~clk_6M; end end
always @(posedge clk_6M) begin
if(mm == 2'b01) outclk <= out1; else if(mm == 2'b00) outclk <= out2; else if(mm == 2'b10) outclk <= out3; else outclk <= out4; end
/*数码管段码表*/
function [6:0] led7; input [3:0] dis_input; begin
case (dis_input)
0 : led7 = ~7'b011_1111; 1 : led7 = ~7'b000_0110; 2 : led7 = ~7'b101_1011; 3 : led7 = ~7'b100_1111; 4 : led7 = ~7'b110_0110; 5 : led7 = ~7'b110_1101; 6 : led7 = ~7'b111_1101; 7 : led7 = ~7'b000_0111; 8 : led7 = ~7'b111_1111; 9 : led7 = ~7'b110_0111;
default : led7 = ~7'b111_1111; endcase end
endfunction
endmodule
20
二、输入控制模块
//digital_piano子模块 module
digital_piano(inclk,key1,key2,key3,key4,key5,key6,key7,beep2,num); input inclk,key1,key2,key3,key4,key5,key6,key7; output[3:0]num;
output beep2; wire [6:0] key_code; reg [3:0]c; reg clk_6M; reg beep_r; reg [3:0]num; reg [15:0] count;
reg [15:0] count_end;
parameter Do = 7'b1111110, //状态机的7个编码,分别对应中音的7个音符 re = 7'b1111101, mi = 7'b1111011, fa = 7'b1110111, so = 7'b1101111, la = 7'b1011111,
si = 7'b0111111;
assign key_code = {key7,key6,key5,key4,key3,key2,key1}; assign beep2 = beep_r; //输出音乐
always@(posedge inclk) begin
if(c<4'd4) c<=c+4'd1; else begin c<=4'd0;
clk_6M=~clk_6M; end end
always@(posedge clk_6M) //分频模块,得出乐谱 begin
count <= count + 16'd1; //计数器加1 if(count == count_end)
21
begin
count <=16'd0; //计数器清零 beep_r <= !beep_r; end end
always@(posedge clk_6M) //状态机,根据按键状态,选择不同的音符输出 begin
case(key_code)
Do: count_end <= 16'd11450; re: count_end <= 16'd10204; mi: count_end <= 16'd09090; fa: count_end <= 16'd08571; so: count_end <= 16'd07802; la: count_end <= 16'd06802; si: count_end <= 16'd06060; default:count_end <= 16'd0; endcase end
always @ (posedge clk_6M) begin
case(key_code)
Do: num<=4'b0001; re: num<=4'b0010; mi: num<=4'b0011; fa: num<=4'b0100; so: num<=4'b0101; la: num<=4'b0110; si: num<=4'b0111; endcase end
endmodule
三、曲目1乐谱存储及循环播放模块
//bell子模块 《两只老虎》
module bell (inclk,beep1);
input inclk; //系统时钟 output beep1; //蜂鸣器输出端 reg [3:0]high,med,low; reg [15:0]origin;
22
reg beep_r; //寄存器 reg [7:0]state; reg [15:0]count;
assign beep1=beep_r; //输出音乐
//时钟频率6MHz reg clk_6MHz; reg [2:0] cnt1;
always@(posedge inclk) begin
if(cnt1<3'd4)
cnt1<=cnt1+3'b1; else
begin
cnt1<=3'b0;
clk_6MHz<=~clk_6MHz; end end
//时钟频率4MHz reg clk_4Hz;
reg [24:0] cnt2; always@(posedge inclk) begin
if(cnt2<25'd6250000) cnt2<=cnt2+25'b1; else
begin
cnt2<=25'b0;
clk_4Hz<=~clk_4Hz; end end
always @(posedge clk_6MHz) begin
count <= count + 1'b1; if(count == origin) begin
count <= 16'h0; beep_r <= !beep_r; end end
always@(posedge clk_4Hz) begin
//计数器加1 //计数器清零 //输出取反 23