Sim's blog

電子工作はじめてみました

diceを動かしてみました

2009-06-17 19:54:27 | FPGA
トラ技2009年6月号の別冊付録「再確認 電子機器の開発ツール」にFPGAの部屋のmarseeさんが、FPGAの開発方法の解説記事を書かれています。そこで使われていたのがdiceというサイコロのサンプルです。VHDLのソースは、FPGAの部屋さんの「ISE11.1iのチュートリアル1(導入編)」という記事に貼り付けてあります。先日買ったLatticeXP2基板「比叡」で動かしてみました。
徒然日記さんがAlteraで動かしているので、Xilinx、Altera、Latticeと3社のFPGAで動作が確認されたことになります。


オリジナルのソースはSpartan-3スタータキット用です。違うところは、比叡には7セグLEDがないので普通のLEDにしてしまったところと、リセットの極性が逆(比叡はアクティブロー)なところ、クロックが比叡は32.768MHz(SP3の方は50MHz)なところです。

使用スライス数は35でした。


VHDLのprocess文を使って非同期リセットを記述するには以下のように書きます。
process(clk, reset) begin
  if(reset = '1') then
    リセット時の動作
  elsif(clk'event and clk = '1') then
    クロック立ち上がり時の動作
  end if;
end process

この例ではresetが1のときにリセット時動作をするのでアクティブハイです。比叡で動作させるには0のときに動作させたいのでifの判定をreset='0'に書き換えることになります。

ちなみにverilogで同じことをalways文を使って書くと次のようになります。
always @(posedge clk or posedge reset)
  if(reset)
    リセット時の動作
  else
    クロック立ち上がり時の動作

ついでに、VHDLの同期リセットです。
process(clk) begin
  if(clk'event and clk = '1') then
    if(reset = '1') then
      リセット時の動作
    else
      クロック立ち上がり時の動作
    end if;
  end if;
end process;

resetのif文がclkのif文の内部に入っているのでクロックに同期しています。またprocessのセンシティビティリストがclkのみになっています。このあたりは、慣用句というか、形で覚えておくとよさそうです。

verilogの同期リセットは次のようになります。
always @(posedge clk)
  if(reset)
    リセット時の動作
  else
    クロック立ち上がり時の動作

verilogでは、センシティビティリストが変わるだけです(posedge resetがなくなります)。

と、ここで気づいたのですが、diceのソースでは以下のような記述になっています。
process(clk) begin
  if(reset = '1') then
    リセット時の動作
  elsif(clk'event and clk = '1') then
    クロック立ち上がり時の動作
  end if;
end process;

私の知っている同期リセットとも非同期リセットとも違います。どのような動作をするんでしょうか?

まだVHDLは、よく分かりません。

6/20 追記 diceのソースの件は、センシティビティリストの書き忘れだったそうです。弘法も筆の誤りといったところでしょうか。marseeさんのフォローの記事「ISE11.1iのチュートリアル1(導入編)の訂正」、徒然日記さんのフォローの記事「非同期リセットと同期リセット」が出ています。ISE、Quartus、ispLEVER、どのツールもwarningは出ていた模様です。合成ツールはたいてい山のようにwarningを吐き出してくれるので、warningに不感症になりやすいです。あまりに多すぎて見る気になれなくなっちゃいます。これはこれで役に立たないというか、重要なwarningを見落とす原因になります。このあたりは何とかしてもらいたいものです。


最新の画像もっと見る

15 コメント

コメント日が  古い順  |   新しい順
VHDLは私もわかりませんが (のりたん)
2009-06-17 21:21:42
「クロックの両エッジでリセットされる同期リセット付きフリップフロップ」でいかがでしょう?

まるで、 DDR RAM のようだ。
返信する
Unknown (nekosan)
2009-06-18 00:47:36
なんとなく、合成はできてかつ想定どおり動くけど、シミュレーションを掛けると想像どおりに動かないっていう記述なきがするんですが…

このdiceというVHDLは実機でちゃんと動いているんですよね。
シミュレーションはどうなんでしょうかね?リセット信号を拾ってくれないんじゃない気がするのですが…
返信する
Unknown (marsee)
2009-06-18 04:33:06
こんにちは。
ごめんなさい。最初に同期FF版Verilog版を作って、その後でVHDL版を作ったので、勘違いしていたみたいです。
ちなみにインプリメントでは、FPGA Editorで見ると非同期リセットになっています。XSTでウォーニングが出ていました。
全体のシミュレーションはしていませんが、ステートマシンはシミュレーションしています。そこでは問題なく見えました。つまり、シミュレータはクロックの立ち上がりエッジイベントでresetが1ならば値が決まるので、問題なく動いているように見えたようです。
いずれにせよ、非同期リセットに修正しておきます。
返信する
Unknown (marsee)
2009-06-18 04:54:50
やはり、チャタリングサンプルクロックの間隔をシミュレーション用に変更して全体シミュレーションもやっていました。シミュレーションでの動作の確認にも問題はないようです。(拡大してみると問題があることが分かると思いますが。。。)
http://marsee101.blog19.fc2.com/blog-entry-1109.html

私のブログのソースを非同期リセットに変更しました。バグのご指摘ありがとうございました。お礼申し上げます。
返信する
re:VHDLは私もわかりませんが (Sim)
2009-06-18 06:40:29
こんにちは、のりたんさん
それって、bothedgeってやつですね。verilog 2015くらいで採用されるといいですね。

返信する
re:Unknown (Sim)
2009-06-18 06:43:52
こんにちは、nekosanさん
後のmarseeさんのコメントにもあるように、合成ツール(XST)は非同期リセットだと思ってくれるみたいです。Latticeの合成ツール(Synplify)も同じみたいでした。
返信する
Unknown (marsee)
2009-06-18 06:50:19
nekosanさん、というわけで一応シミュレーションでもそれらしく動いていました。実機でも動作には問題ないです。
返信する
re:Unknown (Sim)
2009-06-18 06:52:05
こんにちは、marseeさん
非同期リセットだったんですね。
以前からVHDLも読めるくらいにはならないと、と思うだけは思っていてなかなか手がついていなかったんですが、ちょうどいいサンプルがあったと思って勉強がてら読み始めていました。
Synplifyでも、warningが出ていたみたいです。Referenced variable reset_sw is not in sensitivity listというメッセージが出ていました。
やはり勉強するには、他人の書いたソースを研究してみるのがいいみたいです。いい機会を提供していただきありがとうございます。
返信する
Unknown (nekosan)
2009-06-19 00:49:18
marseeさん、simさん

ご解説ありがとうございます。Latticeはウォーニングが出て非同期リセットの扱いになるんですか…

以前センシティビティーリストを間違えて書いてしまったときに、alteraはウォーニングが出ず、しかもシミュレーションがうまく動かなかったという記憶があったので…
(xilinxもそうだったような…)

環境によって色々違うものなんですね。
返信する
re:Unknown (Sim)
2009-06-20 19:18:11
こんにちは、nekosanさん
センシティビティーリストは、verilogでもVHDLでも鬼門ですね。微妙にシミュレーション結果と実装結果が違ったりする原因の一つなので気をつけないといけないです。
今回の件はとても勉強になりました。なんか理解が深まった感じです。
返信する

コメントを投稿