You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

107 lines
2.6 KiB
Verilog

module freq_select(
input wire sys_clk ,
input wire sys_rst_n ,
output wire pwm
);
parameter MAX = 24'd15_000_000;//300ms最大数
parameter NOTE = 6'd34;//音符个数
parameter DO = 16'd47750,//1
RE = 16'd42550,//2
MI = 16'd37900,//3
FA = 16'd37550,//4
SO = 16'd31850,//5
LA = 16'd28400,//6
XI = 16'd25400;//7
reg [23: 0] cnt_300 ;
reg [5: 0] cnt_note;
reg [15: 0] cnt_freq;
wire [15: 0] duty ;//占空比
reg [15: 0] X;
//300ms计数器设计
always @(posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n)begin
cnt_300 <= 24'd0;
end
else if(cnt_300 == MAX - 1'd1)begin
cnt_300 <= 24'd0;
end
else begin
cnt_300 <= cnt_300 + 1'd1;
end
end
//34个音符计数器设计
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
cnt_note <= 6'd0;
end
else if((cnt_note == NOTE - 1'd1) && (cnt_300 == MAX - 1'd1))begin
cnt_note <= 6'd0;
end
else if(cnt_300 == MAX - 1'd1)begin
cnt_note <= cnt_note + 1'd1;
end
else begin
cnt_note <= cnt_note;
end
end
//每个音符频率计数器
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
cnt_freq <= 16'd0;
end
else if(cnt_freq == X - 1)begin
cnt_freq <= 16'd0;
end
else begin
cnt_freq <= cnt_freq + 1'd1;
end
end
//查找表
always @(*)begin
case(cnt_note)
6'd0 : X = DO;//1
6'd1 : X = RE;//2
6'd2 : X = MI;//3
6'd3 : X = DO;//1
6'd4 : X = DO;//1
6'd5 : X = RE;//2
6'd6 : X = MI;//3
6'd7 : X = DO;//1
6'd8 : X = MI;//3
6'd9 : X = FA;//4
6'd10 : X = SO;//5
6'd11 : X = MI;//3
6'd12 : X = FA;//4
6'd13 : X = SO;//5
6'd14 : X = SO;//5
6'd15 : X = LA;//6
6'd16 : X = SO;//5
6'd17 : X = FA;//4
6'd18 : X = MI;//3
6'd19 : X = DO;//1
6'd20 : X = SO;//5
6'd21 : X = LA;//6
6'd22 : X = SO;//5
6'd23 : X = FA;//4
6'd24 : X = MI;//3
6'd25 : X = DO;//1
6'd26 : X = RE;//2
6'd27 : X = SO;//5
6'd28 : X = DO;//1
6'd29 : X = DO;//1
6'd30 : X = RE;//2
6'd31 : X = SO;//5
6'd32 : X = DO;//1
6'd33 : X = DO;//1
default: X = DO;//1
endcase
end
assign duty = X >> 1;//占空比是1/2
assign pwm = (cnt_freq >= duty) ? 1'b0: 1'b1;
endmodule