根据输入更改计数器目标

Changing Counter target according to input

我正在做一个数字设计课程的项目,我必须在我的项目中使用频率来演奏音符。我必须说我在 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,我想做的是根据用户输入改变输出频率,所以我假设我只需要改变计数器的值计为。我怎样才能巧妙地将它添加到代码中以使其正常工作?

为了让您入门,我已经为您设置了一个环境。 您必须添加您的逻辑才能实现正确的功能(作业) 特别是在柜台登记处,你必须计算 所需频率。

          // 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