2015-11-24 5 views
1

Я работаю над проектом для курса цифрового дизайна, и я должен играть в музыкальные ноты, используя частоты в моем проекте. Должен сказать, что я довольно неопытен в verilog (нужно использовать verilog для проекта). Я исследовал немного о теме и нашел (here) следующий фрагмент кода:Изменение счетчика в соответствии с вводом

module music(clk, speaker); 
    input clk; 
    output speaker; 
    parameter clkdivider = 25000000/440/2; 

    reg [14:0] counter; 
    always @(posedge clk) if(counter==0) counter <= clkdivider-1; else counter <= counter-1; 

    reg speaker; 
    always @(posedge clk) if(counter==0) speaker <= ~speaker; 
    endmodule 

В этом коде часы является 25MHz, а частота выходного сигнала составляет 440, что я хочу сделать, это изменить частоту выход по пользовательскому вводу, поэтому я предполагаю, что мне просто нужно изменить значение счетчика. Как я могу аккуратно добавить это в код, чтобы он работал?

+0

Вы хотите, чтобы иметь возможность играть одну ноту в то время, или несколько нот в то время? –

+0

Только по одному –

ответ

2

Чтобы начать работу, я настроил для вас среду. Вы должны добавить, что вам нужна логика для правильной работы (домашняя работа) особенно в счетчике, где вам нужно рассчитать требуемую частоту.

  // change logic here (to add userinput) 
      counter <= clkdivider-1; 

Поскольку вы хотите изменить частоту выходного сигнала в соответствии с пользовательским вводом, вы должны добавить входной порт для music модуля.

module music(clk, reset, userinput, valid, speaker); 
    input clk, valid, reset; 
    input [7:0] userinput; 
    output speaker; 

userinput 8 бит, но вы можете изменить это на основе от ваших требований. Обратите внимание, что сигнал valid также необходим для установления связи с другими модулями .

Сброс также добавлен, чтобы очистить ваш модуль music.

Вот ваш испытательный стенд

module testmusic; 
reg clk; 
reg [7:0] userinput; 
wire speaker; 
reg valid; 
reg reset; 


initial begin 
    forever begin 
    #1 clk = !clk; 
    end 
end 

initial begin 
    clk = 0; 
    userinput = 0; 
    valid = 0; 
    @(posedge clk); 
    $monitor("userinput: %0h valid: %0h speaker: %0h\n", userinput, valid, speaker); 
end 


task resetdut; 
    reset = 0; 

    repeat (3) begin 
    @(posedge clk); 
    end 

    reset <= 1; 

    repeat (3) begin 
    @(posedge clk); 
    end 

    reset <= 0; 
endtask 

music dut(clk, reset, userinput, valid, speaker); 

initial begin 
    #10000; $finish; 
end 

// perform our testing here 
initial begin 
    // perform reset to initialize our dut 
    resetdut; 
    testuserinput; 
end 

task testuserinput; 
    @(posedge clk); 
    userinput <= 8'hF; // insert user input here 
    valid <= 1; 
    @(posedge clk); 
    userinput <= 0; 
    valid <= 0; 
    @(posedge clk); 
endtask 


endmodule 

Вот ваш RTL код, который нужно исправить.

module music(clk, reset, userinput, valid, speaker); 
    input clk, valid, reset; 
    input [7:0] userinput; 
    output speaker; 
    parameter clkdivider = 25000000/440/2; 

    reg [14:0] counter; 

    reg [7:0] reginput; 

    always @(posedge clk) begin 
     if (reset) begin 
     counter <= 0; 
     end 
     else begin 
     if(counter==0) begin 
      // change logic here (to add userinput) 
      counter <= clkdivider-1; 
     end 
     else begin 
      counter <= counter-1; 
     end 
     end 
    end 

    reg speaker; 
    always @(posedge clk) begin 
     if (reset) begin 
     speaker <= 0; 
     end 
     else begin 
     if(counter==0) begin 
      speaker <= ~speaker; 
     end 
     end 
    end 

    // handshake 
    always @(posedge clk) begin 
    if (reset) begin 
     reginput <= 0; 
    end 
    else begin 
     if (valid) begin 
      reginput <= userinput; 
     end 
    end 
    end 

endmodule 

Вы можете скомпилировать код здесь http://www.edaplayground.com/x/PR2

+0

Затем сбрасываем форму волны, чтобы увидеть вашу симуляцию. – e19293001

+0

Спасибо, что нашли время ответить. У меня остались вопросы: 1. Можете ли вы объяснить, что делает рукопожатие? 2. Я намерен иметь 12 частот, которые я буду использовать для музыкальных нот, поэтому я предполагаю, что у меня будет вход 4 бит, чтобы определить, какая частота воспроизводится, и я хочу, чтобы счетчик изменился на желаемую частоту (предположим, например, входное значение 4'b0010 означает частоту 390 Гц, поэтому я хочу, чтобы clkdivider изменился на 25000000/390/2, чтобы счетчик подсчитал другое значение. Как это сделать? –

+0

Следует добавить несколько параметров для каждого входа, такого как: параметр input0010 = 25000000/390/2, а затем в счетчике у меня бы был оператор case, и у меня был бы счетчик <= input0010 - 1; при вводе 0010, а также для каждого вход? или есть более аккуратный способ сделать это? –