使用FPGA生成PWM[英] pwm generation using fpga

本文是小编为大家收集整理的关于使用FPGA生成PWM的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

如何使用FPGA生成PWM信号?哪个是生成可变占空比的最佳方法?

我试图通过使用以下代码来解决此问题,但发生了两个或三个错误.

这是我的代码:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

use ieee.numeric_std.all;
--use ieee.float_pkg.all;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.

--library UNISIM;
--use UNISIM.VComponents.all;

entity pwm_sne is
  Generic(
    sys_clk         :integer :=50000000;
    pwm_freq        :integer :=100000;
    bits_resolution :integer :=8
  );
  Port (
    clk : in  STD_LOGIC;
    rst : in  STD_LOGIC;
    k   : in  STD_LOGIC_VECTOR (7 downto 0);
    y   : out STD_LOGIC
  );
end pwm_sne;

architecture Behavioral of pwm_sne is
  signal cnt      :std_logic_vector(7 downto 0);
  signal flag     :std_logic;
  signal reg      :std_logic_vector(7 downto 0);
  --variable duty   :std_logic:=0;
begin
  process(clk,rst)
  begin
    if rst='1' then
      cnt<="00000000";
    elsif(clk'event and clk='1')then
      cnt<=cnt+"00000001";
    elsif cnt="11111111" then
      flag<='0';
      cnt<="00000000";
    end if;
  end process;

  process(clk,flag)
  begin
    if(clk'event and clk='1') then
      reg<=k;
    end if;
  end process;

  process(cnt,reg)
  begin
    if(flag='0')then
    elsif cnt>reg then
      y<=(reg/256)*100;
      --y<=duty;
    elsif cnt=reg then
      y<=(reg/256)*100;
    elsif cnt<=reg then
      y<=period;
      --y<=duty;
    end if;
  end process;
end Behavioral;

错误发生在输出值y和分区操作中.

请提出一种从上方解决问题的好方法.

推荐答案

解决方案:在数字上进行数学,而不是在未经类似的袋子上进行.

如果cnt, reg,k是natural range 0 to 255,并且您将cnt与0或255进行了比较,并在其中添加了1个,这只会工作.如果k必须是std_logic_vector,请在IT和reg之间使用一种类型的转换功能.

还建议:删除非标准std_logic_arith and std_logic_unsigned libs and use numeric_std`.

本文地址:https://www.itbaoku.cn/post/2091012.html

问题描述

How to generate a PWM signal using an FPGA? Which is best method to generate a variable duty cycle?

I tried to solve this problem by using the following code but two or three errors occurred.

This is my code:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

use ieee.numeric_std.all;
--use ieee.float_pkg.all;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.

--library UNISIM;
--use UNISIM.VComponents.all;

entity pwm_sne is
  Generic(
    sys_clk         :integer :=50000000;
    pwm_freq        :integer :=100000;
    bits_resolution :integer :=8
  );
  Port (
    clk : in  STD_LOGIC;
    rst : in  STD_LOGIC;
    k   : in  STD_LOGIC_VECTOR (7 downto 0);
    y   : out STD_LOGIC
  );
end pwm_sne;

architecture Behavioral of pwm_sne is
  signal cnt      :std_logic_vector(7 downto 0);
  signal flag     :std_logic;
  signal reg      :std_logic_vector(7 downto 0);
  --variable duty   :std_logic:=0;
begin
  process(clk,rst)
  begin
    if rst='1' then
      cnt<="00000000";
    elsif(clk'event and clk='1')then
      cnt<=cnt+"00000001";
    elsif cnt="11111111" then
      flag<='0';
      cnt<="00000000";
    end if;
  end process;

  process(clk,flag)
  begin
    if(clk'event and clk='1') then
      reg<=k;
    end if;
  end process;

  process(cnt,reg)
  begin
    if(flag='0')then
    elsif cnt>reg then
      y<=(reg/256)*100;
      --y<=duty;
    elsif cnt=reg then
      y<=(reg/256)*100;
    elsif cnt<=reg then
      y<=period;
      --y<=duty;
    end if;
  end process;
end Behavioral;

The errors occurred in output value y and at the division operation.

Please suggest a good method to solve the problems from above.

推荐答案

Solution : Do maths on numbers, not on untyped bags of bits.

If cnt, reg,k were natural range 0 to 255 and you compared cnt with 0 or 255 and added 1 to it, this would just work. And if k MUST be std_logic_vector, use ONE type conversion function between it and reg.

Also recommended : delete the non-standard std_logic_arith andstd_logic_unsignedlibs and usenumeric_std` instead.