我正在尝试使用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)。另外,我想了解一下我可以产生脉冲的速度(上升/下降时间和频率)(物理限制)。
我希望有经验的用户提供一些指导。
答案 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,由于初始“无效”时钟导致的初始时序违规,标志变量(状态)将不会按预期运行,依此类推。修改此方法的一种方法是添加一个复位输入并将其应用于变量状态,直到时钟稳定,或使用不等运算符进行比较。