VHDL-PWM奇怪行为和物理上/下限制

时间:2013-07-09 14:18:39

标签: vhdl fpga xilinx pwm

我正在尝试使用VHDL(Xilinx ISE + ISim)中的Spartan 3e板生成皮秒PWM信号。

library ieee;
use ieee.std_logic_1164.all;

entity pwm is
  port(clk     : in     std_logic;
       pwm_out : buffer std_logic);
end entity;

architecture rtl of pwm is
begin
  process (clk)
    variable count      : integer range 0 to 50000;
    variable duty_cycle : integer range 0 to 50000;
    variable flag       : integer range 0 to 1;
  begin
    if (rising_edge(clk)) then
      count := count+1;
      if (count = duty_cycle) then
        pwm_out <= '1';
      end if;
      if (count = 50000) then
        pwm_out <= '0';
        count   := 0;
        if(flag = 0) then
          duty_cycle := duty_cycle+50;
        else
          duty_cycle := duty_cycle-50;
        end if;
        if(duty_cycle = 50000) then
          flag := 1;
        elsif(duty_cycle = 0) then
          flag := 0;
        end if;
      end if;
    end if;
  end process;
end rtl;

我使用嵌入式50Mhz作为全局时钟(C9),但模拟显示出奇怪的行为;从0ps到1000000ps clk(时钟)和pwm_out(输出)似乎总是HIGH,并且在ISim下的时域中clk和pwm_out都没有1000000ps。

我想做的是调查并解决此行为,然后增加输出频率(pwm_out)。另外,我想了解一下我可以产生脉冲的速度(上升/下降时间和频率)(物理限制)。

我希望有经验的用户提供一些指导。

1 个答案:

答案 0 :(得分:0)

pwm_out输出没有初始值,因此必须在获得定义良好的值之前在过程中分配它。但是过程变量(保持过程状态)都具有零的初始值,并且由于计数在过程循环中首先递增,因此count在开始时将不等于duty_cycle(为0)。所以pwm_out在它等于50000之前不会被分配,其中(50 MHz时钟)发生在50000/50 MHz = 1 ms。

但是,如果您将其合成并在FPGA中运行,则可能会遇到一些意外行为,具体取决于您的时钟源和控制。例如,如果pwm模块在加载FPGA时从一个不稳定的时钟运行,例如内部PLL时钟,那么初始时钟行为可能不符合应用于设计的时序约束,并且任何值最终可能会出现在duty_cycle变量(寄存器)中。但是,该设计基于这样的假设:duty_cycle寄存器的值为(50 * n),否则由于0和50000的相等比较(=),它将不会按预期递增和递减。所以如果duty_cycle获取值1,由于初始“无效”时钟导致的初始时序违规,标志变量(状态)将不会按预期运行,依此类推。修改此方法的一种方法是添加一个复位输入并将其应用于变量状态,直到时钟稳定,或使用不等运算符进行比较。