⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 music_tune.v

📁 基于FPGA的VHDL编程实现各种音频信号
💻 V
字号:
// music_tune.v

module music_tune(clk, speaker);
input clk;
output speaker;

//To play a range of increasing notes, we instantiate a 28 bits counter,
// from which we extract the 6 most significant bits, to give us the 6 bits
//  of the note we want to play.
//确定音调的范围
reg [27:0] tone;
always @(posedge clk) tone <= tone+1;

wire [5:0] fullnote = tone[27:22];

//We divide the "fullnote" by 12. That gives us the octave (5 octaves, so 3 bits are
// enough, since it goes from 0 to 4) and the note (from 0 to 11, so 4 bits).

wire [2:0] octave;
wire [3:0] note;
divide_by12 divby12(.numer(fullnote[5:0]), .quotient(octave), .remain(note));

/*
To go from one octave to the next, frequency is multiplied by "2". Easy to do 
in hardware, we do that in step 4.
To go from one note to the next, frequency is multiplied by "1.0594". Not really
 easy to do in hardware. So we use a look-up table with pre-calculated values.

We divide the main clock by 512 for note A, by 483 for note A#, by 456 for note B...
 Remember, dividing by a lower value gives us a higher frequency/higher note, that's
 what we want.
*/
reg [8:0] clkdivider;
always @(note)
case(note)
  0: clkdivider = 512-1; // A 
  1: clkdivider = 483-1; // A#/Bb
  2: clkdivider = 456-1; // B 
  3: clkdivider = 431-1; // C 
  4: clkdivider = 406-1; // C#/Db
  5: clkdivider = 384-1; // D 
  6: clkdivider = 362-1; // D#/Eb
  7: clkdivider = 342-1; // E 
  8: clkdivider = 323-1; // F 
  9: clkdivider = 304-1; // F#/Gb
  10: clkdivider = 287-1; // G 
  11: clkdivider = 271-1; // G#/Ab
  12: clkdivider = 0; // should never happen
  13: clkdivider = 0; // should never happen
  14: clkdivider = 0; // should never happen
  15: clkdivider = 0; // should never happen
endcase
//
reg [8:0] counter_note;
always @(posedge clk) 
if(counter_note==0)
     counter_note <= clkdivider; 
else counter_note <= counter_note-1;

reg [7:0] counter_octave;
always @(posedge clk)
if(counter_note==0)
begin
 if(counter_octave==0)
  counter_octave <= (octave==0?255:octave==1?127:octave==2?63:octave==3?31:octave==4?15:7);
 else
  counter_octave <= counter_octave-1;
end

reg speaker;
always @(posedge clk) if(counter_note==0 && counter_octave==0) speaker <= ~speaker;

endmodule 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -