0

我正在尝试使用 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(输出)似乎总是高,并且在 ISim 下的时域中 clk 和 pwm_out 在 1000000ps 之后什么都没有。

我正在尝试做的是调查和解决这种行为,然后增加输出频率(pwm_out)。此外,我想了解生成脉冲的速度(上升/下降时间和频率)(物理限制)。

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

4

1 回答 1

0

pwm_out 输出没有初始值,因此必须在进程中对其进行分配,然后才能获得明确定义的值。但是流程变量(保持流程状态)的初始值都为零,并且由于 count 在流程循环中首先递增,因此 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,由于初始“无效”时钟导致初始时序违规,标志变量(状态)不会按预期运行,等等。修改它的一种方法是添加一个复位输入并将其应用于变量状态,直到时钟稳定,或者使用不等式运算符进行比较。

于 2013-07-09T16:52:24.323 回答