【问题标题】:Changing Counter target according to input根据输入更改计数器目标
【发布时间】:2016-02-26 14:28:00
【问题描述】:

我正在为数字设计课程做一个项目,我必须在我的项目中使用频率来演奏音符。我必须说我在verilog方面相当缺乏经验(必须在项目中使用verilog)。我对该主题进行了一些研究,发现(here)以下代码sn-p:

    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,我想做的是根据用户输入改变输出频率,所以我假设我只需要将计数器计数的值更改为.我怎样才能巧妙地将它添加到代码中以便它应该工作?

【问题讨论】:

  • 您希望一次演奏一个音符还是一次演奏多个音符?

标签: verilog fpga spartan


【解决方案1】:

为了让您开始,我已经为您设置了一个环境。 您必须添加您的逻辑以实现正确的功能(作业) 特别是在计数器寄存器中,您必须计算 所需的频率。

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

【讨论】:

  • 然后转储波形以查看您的模拟。
  • 感谢您花时间回答。我还有一些问题: 1. 你能解释一下握手是做什么的吗? 2. 我打算有 12 个频率用于音符,所以我想我将输入 4 位来确定播放哪个频率,并且我希望计数器更改为所需的频率(假设为示例输入值 4'b0010 代表频率 390 Hz,所以我希望 clkdivider 更改为 25000000/390/2,以便计数器计数到不同的值。我该怎么做?
  • 是否应该为每个输入添加多个参数,例如:参数 input0010 = 25000000/390/2;然后在柜台我有一个案例陈述,我有 counter
  • 1.这是单向握手。 Here 是对双向握手的解释。单次握手的想法仍然相同。
  • 2.这将是一个漫长的讨论。在我的个人资料上发送电子邮件以进一步帮助您。
猜你喜欢
  • 2019-01-30
  • 2014-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-06
  • 1970-01-01
  • 2021-03-21
  • 2021-12-15
相关资源
最近更新 更多