2013/02/02

[電子工作]FPGAでPWM

,
 高速なPWM信号を得ようと思うと、なかなかマイコンでは難しいものがあります。例えば、Arduinoだと大体490Hzらしいです(参考:Arduino 日本語リファレンス)。なので、FPGAで書いてみました。

VHDLコード
-- pwm module 2013-1-18
-- internal counter:0~100

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.std_logic_arith.all;

entity pwm2 is
 port( COMP: in std_logic_vector(6 downto 0);
   CLK: in std_logic;
   SIG: out std_logic);
end pwm2;

architecture RTL of pwm2 is
 signal BUF: std_logic;
 signal COUNTER: std_logic_vector(6 downto 0);
 begin
  process(CLK)
  begin

   if(CLK'event and CLK = '1') then

    if COUNTER <= COMP then
     BUF <= '1';
    else
     BUF <= '0';
    end if;
   
    if COUNTER < "1100100" then 
     COUNTER <= COUNTER + "0000001";
    else
     COUNTER <= "0000000";
    end if;
   end if;
  end process;
  
 SIG <= BUF;
end RTL;
(このVHDL用スクリプトはenrico::garante: Syntax Highlighter 3 VHDL Brushさんのをお借りしました。ライセンス大丈夫なのかな)

 動作の仕組みは単純で、カウンターを0~99まで動かして、デューティ比が75%なら、カウンターが75になるまで出力High、それ以降はLowを繰り返すだけです。

use IEEE.std_logic_unsigned.all;
use IEEE.std_logic_arith.all;
は、std_logic_vector同士を"+"記号で加算するのに必要です。私の持っている本だと
library ARITHMETIC;
use ARITHMETIC.***.all;
を使えと書かれていましたが、これだとQuartus2ではコンパイルが通りますが、ModelSimでUnknown identifier "arithmetic".と弾かれてしまいました。一応synopsys/arithmeticはあるけれど、こっちのほうが早い…

 これとは別に、input_moduleというただ入力をバッファするだけのブロックを作って、以下のように接続しました。
Block1.bdf
[File]→[Export]でjpgにしてみましたけど、なんか左端が切れてしまいますね…

 この.bdf(Block Diagram/Schematic File)は、プログラム書くことなくモジュール同士をつないだりできるので楽ですが、VHDLファイルとの相互変換が今までよくわかってませんでした… 
 やり方は、[File]→[Create / Update]→[Create Symbol Files for Current File]で、シンボルが生成されるみたいです。後は、bdfファイルを新規作成するなりして、その上でダブルクリックするとシンボルが選べるようになっているので追加です。(Cyclone PLL Quartusの最上位(Blok Diagram/Schematic File) ブロック図の作成方さんを参考にしました)
 
Symbolをbdfに追加する画面。こんな風にエンティティのシンボルが追加されてる

 逆に、bdfファイルからVHDLコードに変換するには、[File]→[Create / Update]→[Create HDL Design File for Current File]で、VerilogかVHDLの好きな方にチェックが入っているのを確認して[OK]です。
 ただし、同じエンティティのbdfファイルとコードファイルの両方がプロジェクトに追加されていると、エラーになってしまうみたいです。どちらか一つだけをプロジェクトに残しておきましょう。
(追記 2013/08/24)馬鹿なので、bdfファイルとVHDLファイルを両方プロジェクトに含ませてしまうというエラーをもっかいやりました。エラー内容は以下の様な感じ。
Error (12049): Can't compile duplicate declarations of entity "*******" into library "work"
どっちかを削除しましょう。

 得られた波形はこんな感じです。
デューティ比75%
デューティ比75%の時のrise
デューティ比50%
デューティ比25%
PWMの周波数が495kHzなのは、DE0でFPGAに供給されるCLKが50MHz、カウンターが100までなので大体あってますね。

 [Processing]→[Compilation Report]によれば、この最大周波数は250MHzらしいです。

 ModelSimでシミュレート結果を見るまでは、以下のサイトを参考にさせていただきました。ただ、動作が重くて我がPCだと少し使いづらいです…(起動する所で放置してる)

FPGAの部屋 システム開発入門[Altera偏]を試してみる4(2.4アップダウン・カウンタのシミュレーション1) http://marsee101.blog19.fc2.com/blog-entry-1950.html

Simulating the Virtual JTAG in ModelSim | Idle-Logic http://idle-logic.com/2012/05/28/simulating-the-virtual-jtag-in-modelsim/

ModelSim: VHDLシミュレーション http://www.elc.ees.saitama-u.ac.jp/ITO/vhdl/modelsim.html


 DE0ボードへの書き込みも久々で忘れてました… P6つくろうブログ: FPGAボードDE0の使用方法(2)さんの記事を参考に。SRAM書き込みはPROGじゃなくてRUN側だったのか…

 これだけでもいろいろと詰まるところがあって時間かかりました… 高性能で多機能なIDEですけど、使いこなすのは大変ですね…

0 コメント to “[電子工作]FPGAでPWM”

コメントを投稿