FC2カウンター FPGAの部屋 2010年12月
fc2ブログ

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

ハンターマウンテン塩原スキー場に行ってきました

昨日、ハンターマウンテン塩原スキー場に行ってきました。
去年早めに足が終わってしまったので、今日はこの日のために、1年間、朝100回(少ない。。。)のスクワットを欠かさずしてきました。その成果が現れるかどうか?結果は、去年よりも足が持って、成果が現れているようでした。これからも欠かさず続けたいと思います。
さて、スキー場に8時ころ到着したときは、晴れていたのですが、午前中滑っているときは曇ってきました。いつものクワッドリフトを滑っていると、リフトに乗っているときの寒さが半端ではありません。今日はほんとうに寒い。。。
11時20分ころ、休憩と昼食にしました。休憩に入る前にとった写真です。
Hunter_Ski_1_101231.jpg

昼食にしました。私はクリームパスタにしました。890円です。なかなか美味しかったですが、もう少しパスタが固く茹でてあると良かったです。
Hunter_Ski_2_101231.jpg

食事をしている間に雪が降ってきました。更に寒そうです。午後からはゴンドラで滑ることにしました。ゴンドラは子供たちが急な斜面を滑るのを怖がっていたので、乗ったことがなかったのですが、今回は寒さに負けて乗ってみることにしました。高1の息子は最初はビビっていたのですが、滑ったら急斜面(中斜面位)の方がスリルがあって面白いと言ってました。滑り降りるスピードも速い。。。はまってしまったようです。しかし、小6の娘には少しきついようです。3本ゴンドラをやって休憩。
寒かったし、今日は帰ることになりました。私の足の疲労度もちょうど帰ったほうが良いくらいだったので、2時30分ころ帰り支度を始めました。おみやげを購入して3時ころ帰路に。
雪が降っています。道も雪道でした。帰りは鬼怒川温泉を通って行きました。山を降りるまでは慎重に30Km/h程度で下っていきます。スタッドレスタイヤは、4シーズン目のブリジストン、ブリザックREV01ですが、問題なくグリップしました。鬼怒川温泉辺りも雪でした。積もってはいませんでしたが。。。その後は、真岡辺りまで、ものすごいみぞれ、あられでした。ほんとうに凄い降り。早めに出てきて良かったです。つくばに着くと、全く降っていません。気象の変化にはびっくりました。今日もハンターマウンテン塩原スキー場は雪なんでしょうね?

そうそう、書き忘れましたが、雪は新雪でとっても良かったです。キュキュと音がなりました。急な斜面では、少しアイスバーンもありましたが、全体的に良い雪でした。ハンターでは珍しいですね。いつもはアイスバーンが多いので。。。
  1. 2010年12月31日 05:24 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:0

The Simple MicroBlaze Microcontroller 19 (SCCB設定レジスタを設定できたが...)

シミュレーションも大丈夫のようなので、もう一度、実機で確かめてみた。やはり、SCCB設定レジスタに設定できない。もしかして?と思って、同じ設定レジスタにもう一度設定するようにしたら設定できた。。。

        // state check
        switch (setting_item) {
            case AGC_SET :
                if (current_state == SETTING_ITEM_ST){
                    if (rot_pulse == left_pulse)
                        setting_item = MIRROR_SET;
                    else if (rot_pulse == right_pulse)
                        setting_item = GAIN_LEVEL_SET;
                } else { // AGC ON -> OFF, OFF -> ON
                    if (rot_pulse != no_pulse){
                        if (agc_reg){
                            agc_reg = 0;
                            reg13 = AGC_OFF_2_SCCB13;
                        }else{
                            agc_reg = 1;
                            reg13 = AGC_ON_2_SCCB13;
                        }
                        while (XIo_In8(STATUS_ADDR) & 0x08) ; // SCCB_busy
                        *SCCB_Reg_Write = (((0x13)<<8) | reg13); // Dummy Write
                        while (XIo_In8(STATUS_ADDR) & 0x08) ; // SCCB_busy
                        *SCCB_Reg_Write = (((0x13)<<8) | reg13); // addr data
                    }
                }
                break;


*SCCB_Reg_Write = (((0x13)<<8) | reg13);を2回書いたら、AGCがON,OFFできた(必ずしも、同じアドレスに同じデータを2回ということではなく、1回どこのアドレスにでもWriteすれば後のWriteはOKのように見える)。
だが、初期化は出来ているはず?間をおくとだめなんだろうか?SCCBのデータはハイインピーダンスにしている。下のタイミングチャートのsdaの最後の頃が'Z'になっていると思う。
SMM_65_101228.png

だが、CMOSカメラモジュールでプルアップしているはず。。。
試しに、FPGAの内部プルアップを使用してみた。

NET "cam_sio_d" LOC = "AB2" | IOSTANDARD = LVTTL | PULLUP ;


やはり、変化がない。やはり、2度書きしないとだめだ。

それでは、初期化でも最初の設定はミスっているのか?それを調べるために、最初にAGC ON,OFFを決定するレジスタ0x13にAGC OFFの設定を書いてみた。

13EB


インプリメントして、やってみるとAGCはOFFで問題なかった。では、初期化では最初の設定も問題がないようだ。
ちょっと訳が分からなくなったが、sdaを'Z'にしないで1にドライブし続けようと思う。(やってみたが結果は変化なし)

操作について説明すると、LCDの1行目がSCCB設定レジスタを示す。下の写真ではAGCのゲインを設定する。今は000なので、下のステータス表示行のGの後に000と表示されている。ちなみにGはAGC ONを表す。Gが表示されない場合はAGC OFFだ。
SMM_66_101229.jpg

ロータリーエンコーダを押すと、1行目の最後に'E’が表示されて、ロータリーエンコーダを回すと値が増減できる。
SMM_67_101229.jpg
  1. 2010年12月29日 14:48 |
  2. SMM
  3. | トラックバック:0
  4. | コメント:2

The Simple MicroBlaze Microcontroller 18 (CMOSカメラ回路のシミュレーション)

SMMのシミュレーションをISE12.4のISimで行った。”The Simple MicroBlaze Microcontroller 6(シミュレーション)”を参考にして、SMMのシミュレーション用VHDLファイル、lcd_rot_cont_smm.vhdを作った。と言っても変更したのは、スティミュラスの部分だけで、とてもシンプルな変更だ。変更点を下に示す。

    process begin
        DOUT <= (others => '0');
        BE <= (others => '0');
        ADDR <= (others => '0');
        CS <= '0';
        
        wait for 100 ns;
        
        -- これから下のwaitまでの間にスティミュラスを書く
        
        -- SMM_WR_CYCLE(TIMER_ADDR, X"00000010", "1111", clk, rnw, cs, addr, dout, be); -- Timerへ書き込み、16クロックカウント
        
        -- wait until INTERRUPT_ACK_node'event and INTERRUPT_ACK_node='1'; -- INTERRUPT_ACK_node の立ち上がりまでwait
        -- wait for 1 ns;
        
        -- SMM_WR_CYCLE(LCD_ADDR, X"12340000", "1111", clk, rnw, cs, addr, dout, be); -- LCDへ書き込み
        
        -- -- ボタンの状況をrd_dataに読み出し
        -- SMM_RD_CYCLE(BUTTON_ADDR, "1111", rd_data, clk, rnw, cs, addr, din, be);
        
        wait for 460 us;
        
        SMM_WR_CYCLE(SCCB_REG_WR, X"12340000", "1111", clk, rnw, cs, addr, dout, be); -- OV7670の設定レジスタへ書き込み
        
        wait;
    end process;


CMOSカメラ回路(現在は、CMOSカメラ回路にSMMを組み込んでCMOSカメラの設定レジスタの設定をしようと思っている)のISimシミュレーション用のバッチファイル (CamDispCntrler_DDR2_tb.bat) を下に示す。

rm CamDispCntrler_DDR2_tb.exe
K:\HDL\Xilinx\12.4\ISE_DS\ISE\bin\nt\fuse work.CamDispCntrler_DDR2_tb work.glbl -incremental -d OVL_VERLOG -i ..\ -i ..\..\..\DDR2_SDRAM_cont_266\Simulation\512Mb_ddr2 -i H:\HDL\OVL\std_ovl -d sg3 -d x16 -d OVL_ASSERT_ON -d OVL_FINISH_OFF -L unisims_ver=%XILINX%\verilog\hdp\nt\unisims_ver -L unimacro_ver=%XILINX%\verilog\hdp\nt\unimacro_ver -L XilinxCoreLib_ver=%XILINX%\verilog\hdp\nt\xilinxcorelib_ver -L accellera_ovl_vlog=%XILINX%\verilog\hdp\nt\accellera_ovl_vlog -o CamDispCntrler_DDR2_tb.exe -prj CamDispCntrler_DDR2_Capt_SCCB_tb.prj
CamDispCntrler_DDR2_tb.exe -gui


CamDispCntrler_DDR2_tb.batを実行すると、CamDispCntrler_DDR2_Capt_SCCB_tb.prjのコンパイルを実行して、リンクし、CamDispCntrler_DDR2_tb.exeができるので、それを実行するとISimが走って、シミュレーションができる。
CamDispCntrler_DDR2_Capt_SCCB_tb.prjの内容を下に示す。

verilog work ../../../DDR2_SDRAM_cont_266/Sources/ddr2_sdram_cont/addr_fifo.v
verilog work ../../../DDR2_SDRAM_cont_266/Sources/ddr2_sdram_cont/async_fifo_fall.v
verilog work ../../../DDR2_SDRAM_cont_266/Sources/ddr2_sdram_cont/async_fifo_rise.v
verilog work ../../../DDR2_SDRAM_cont_266/Sources/ddr2_sdram_cont/controller.v
verilog work ../../../DDR2_SDRAM_cont_266/Sources/ddr2_sdram_cont/dcm_module.v
verilog work ../../../DDR2_SDRAM_cont_266/Sources/ddr2_sdram_cont/ddr2_cont_iob.v
verilog work ../../../DDR2_SDRAM_cont_266/Sources/ddr2_sdram_cont/dm_io_pad.v
verilog work ../../../DDR2_SDRAM_cont_266/Sources/ddr2_sdram_cont/dq_io_pad.v
verilog work ../../../DDR2_SDRAM_cont_266/Sources/ddr2_sdram_cont/dqs_io_pad.v
verilog work ../../../DDR2_SDRAM_cont_266/Sources/ddr2_sdram_cont/dqsb_io_pad.v
verilog work ../../../DDR2_SDRAM_cont_266/Sources/ddr2_sdram_cont/rddata_afifo.v
verilog work ../../../DDR2_SDRAM_cont_266/Sources/ddr2_sdram_cont/read_write_io.v
verilog work ../../../DDR2_SDRAM_cont_266/Sources/ddr2_sdram_cont/REFREQSM.v
verilog work ../../../DDR2_SDRAM_cont_266/Sources/ddr2_sdram_cont/wrdata_fifo.v
verilog work ../../../DDR2_SDRAM_cont_266/Sources/ddr2_sdram_cont/ddr2_sdram_cont.v
verilog work "../../Synth122/ipcore_dir/cam_cont_afifo.v"
verilog work "../../Synth122/ipcore_dir/cam_data_afifo.v"
verilog work ../../Sources/SWDiv.v
verilog work ../../Sources/SW_Controller.v
verilog work ../../Sources/VGA_Display_Controller.v
verilog work ../../Sources/Arbiter.v
verilog work ../../Sources/Camera_Controller.v
verilog work ../../Sources/dcm_CAM_DDR2_clk.v
verilog work ../../Sources/synchronizer.v
vhdl work ../../Sources/freqdiv.vhd
vhdl work ../../Sources/One_Transaction_SCCB.vhd
vhdl work ../../Sources/SCCB_Reg_Controller.vhd
vhdl work ../../Sources/SCCB_reg_values_ROM.vhd
vhdl work ../../Sources/lcd_rot_cont.vhd
vhdl work ../SMM_noUART_sim_pack.vhd
vhdl work ../lcd_rot_cont_smm.vhd
vhdl work ../../Sources/lcd_ctlr.vhd
vhdl work ../../Sources/timer.vhd
vhdl work ../../Sources/rot_enc_cont.vhd
vhdl work ../../Sources/swdiv_rot.vhd
vhdl work ../../Sources/ROTSW_SM.vhd
verilog work ../../Sources/CamDisp_Cntrler_DDR2.v
verilog work ../OV7670_Model.v
verilog work H:\HDL\FndtnISEWork\Spartan3A_starter_kit\DDR2_SDRAM_cont_266\Simulation\512Mb_ddr2\ddr2.v
verilog work ../CamDispCntrler_DDR2_tb.v
verilog work H:\HDL\Xilinx\12.2\ISE_DS\ISE\verilog\src\glbl.v


VerilogとVHDLを混在でシミュレーションしている。Verilog、VHDL混在でシミュレーション出来るのはISimの大きな利点の一つだ。ModelSim SEだったら混在行けるけど、なかなか混在でシミュレーションできるシミュレーターは少ないし高価だ。
これでコンパイルしたら、エラーになってしまった。OVLアサーションを入れてあるので、OVLのライブラリが無かったのがエラーの原因だった。
ISimでOVLのVHDL, Verilog混在シミュレーション(OVLライブラリのコンパイルと登録)”を見ながら、ISE12.4でOVLをコンパイルしてライブラリ化した。(この記事が間違っていたで、修正しました。VHDLライブラリがコンパイル出来なかった)
OVLライブラリを生成してリンクしたら、コンパイルが通って、ISimが立ち上がった。
起動時にOV7670の設定レジスタをセットするが、それを1つにして、SMMから12番アドバイスに34というデータを書きこむスティミュラスを試してみた。この記事の一番上のリストがそれだ。
シミュレーション結果を下に示す。
SMM_65_101228.png

実線のカーソルが初期化時のSCCBインタフェースの波形(設定レジスタ書き込み)で、破線のカーソルがSMMから12番アドバイスに34というデータを書きこむ波形だ。
これを見る限り、上手くいっているようなんだが?なぜ設定がうまくいかないんだろう?初期化時には問題なく上手くいっているんだけど?もう一度SDKでデバックしてみよう。それで上手くいっているようであれば、オシロスコープで見てみたい。
  1. 2010年12月28日 09:15 |
  2. SMM
  3. | トラックバック:0
  4. | コメント:0

2010年を振り返る

今年も終わりなので、2010年を振り返ってみようと思う。

1月
・ISE11.4が出た。
・Spartan3A Starter KitのビットマップVGAコントローラの仕様の策定
・キャラクタ生成コントローラの仕様の策定

2月
・キャラクタ描画テスト回路を作成中(なかなか動作せず)
・ビットマップVGAコントローラを単体で動作させた
・キャラクタ描画テスト回路をデバック(テスト回路を入れたり、配線を固定したりした)
・キャラクタ描画テスト回路がうまくいかないので休止
・真壁のひなまつりに行った
・Verification Engineerの戯言さんの”SystemVerilogの世界へようこそ”のWebサイトの”無償ツールで実践する「ハード・ソフト協調検証」(全8回)”をやってみた

3月
・Verification Engineerの戯言さんの”SystemVerilogの世界へようこそ”のWebサイトの”無償ツールで実践する「ハード・ソフト協調検証」(全8回)”をやってみたの続き
・OVL(Open Verification Library)を試してみた(アサーション)
・蔵王スキー(今年は娘が受験なので行けない。。。)
・DDR3 SDRAMの新機能についてまとめた

4月
・Spartan-6 FPGA SP605 評価キットをいじるためにSpartan-6の内部構造を調べた
・ISimでOVLのVHDL, Verilog混在シミュレーション
・SP605のBase Reference Designをやってみた
・Spartan-6のMemory Contoller Block(MCB)の勉強
・SP605のMCBをISimでシミュレーションする

5月
・SP605用のMCBのインプリメント
・ISE12.1がでた
・SystemVerilog、VerilogをDoxygenでドキュメント化
・Virtex-6 ファミリ デザイン セミナに行ってきた
・SP605でPCIe Coreを生成してみた
・シミュレーションでSpartan-6のPCIe Endpoint Block IPの勉強をした

6月
・CoreGenからChipScope Proを使用した(ChipScope コアをインスタンスした)
・Spartan-6のPCIe Endpoint Block IPの勉強の続き
・娘の高校の文化祭に行ってきた(3年生なので、もう終わりと思うと寂しいけど、息子がいるし)
・PCI Expressのトランザクション・パケット解析ソフトをOpenOffice.orgのCalcで作った
・画像センシングシンポジウムに行ってきました
・ISim単体でのシミュレーション方法
・The Simple MicroBlaze Microcontrollerが出ていた
・Virtex-7, Kintex-7, Artix-7発表
・SP605でキャラクタ・ディスプレイ・コントローラ(CH7301Cを使うように改造した)
・Spartan-6のGTPトランシーバの勉強

7月
・ChipScope ProのVIO (Virtual Input/Output core)について書いた
・XUP USB-JTAG Programming Cableを試した(OKだった)
・Spartan-3A Starter KitでCMOSカメラ・ディスプレイ回路をやり始めた(仕様策定)
・ChipScope ProのVIOをtclスクリプトで制御したみた
・ブルーベリー、ブラックベリー収穫、でも虫刺された。痛かった

8月
・Spartan-3A Starter KitでCMOSカメラ・ディスプレイ回路のインプリメント
・配置配線後にそのコンポーネントの配置の制約をUCFファイルに書き出す方法
・Spartan-3A Starter KitでCMOSカメラ・ディスプレイ回路はケーブルノイズが酷かった。アルミ箔をまいたら大分良くなった
・さらにカメラのピントを合わせたら画像が出てきたが、まだノイズが入っていた
・カラーにすると色がおかしい
・DE0のSDR SDRAMコントローラ始めたけど、止まっている
・Spartan-3A Starter KitでCMOSカメラ・ディスプレイ回路でカメラをケーブルから基板接続に変更した
・Spartan-3A Starter KitでCMOSカメラ・ディスプレイ回路の画像ノイズのバグが修正できた

9月
・Spartan-3A Starter KitでCMOSカメラ・ディスプレイ回路にChipScope ProのVIOを入れて、tclでデータを取得した
・どうも色がおかしい
・CMOSカメラ・ディスプレイ回路にSCCBインタフェース回路を実装した
・LinuxのOV7670のドライバを参考にして、レジスタを設定したらまともな色が出た。良かった。。。
・ジブリ美術館に行ってきた
・DE0にCMOSカメラを搭載するのを画策した(今のところペンディング)
・DE0のCMOSカメラ回路を移植するためにいろいろやった
・CMOSカメラのプロジェクトを公開した

10月
・イノベーションジャパンで仕事用の回路を展示した
・割り算器が必要になったので、ISE12.2のCore GeneratorのDivider Generator を使って割り算コアを生成してみた
・アリエッティ展、浅草寺に行ってきた
・PlanAheadのプロジェクトを試してみたが、まだまだかな?
・DE0のSDR SDRAMコントローラをデバック(ペンディング)
・AlteraのFPGAについて勉強した
・富弘美術館、草木ダムに行ってきました
・Spartan-3A Starter Kit用の基板スタンドを作った
・10ビットの2進数から3桁のBCD(Binary-coded decimal)への変換回路(皆さん、良い回路を教えてくれてありがとうございます)

11月
・Make06出展準備
・Spartan-3A Starter Kitによる画像演奏装置(きらきら星)
・Spartan-3A Starter Kitによる画像演奏装置(手で演奏モード)
・Make Tokyo Meeting 06出展
・The Simple MicroBlaze Microcontroller(SMM)を勉強
・SMMのリファレンス・デザインをやってみた
・SMMデバック機能を確かめた

12月
・SMMのシミュレーション
・ET2010に行った。井倉さんとお会いした
・SMMにロータリーエンコーダとSCCBインタフェース回路を接続
・SMMのCソフトウェアを書いた
・VHDLで*演算子を使ったときの乗算について調べた
・Cソフトウェアが入らなかったので、XPSを使ってBRAMを8Kから16KBにした
・デバックをしながら今に至る

現在の課題は、SMMのno_Debugのコンフィグの物にもデバックモジュール(MDM)が入っているので、ChipScopeが使えない。そこで、解決策を探したが見つからない。そこで、シミュレーションでデバックをしようとしている。

今年もいろいろやったな~と改めて思う。これだけのことをやったんだ。ブログを書きながら良くやったと思う。こうして分かるのもブログを書いているからだと思う。

そういえば、今年は映画をよく見た。14作品を見た。

FPGA技術No.6にも書かせていただいた。うれしいです。

来年も頑張ろう~!!!
  1. 2010年12月26日 22:08 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:0

The Simple MicroBlaze Microcontroller 17 (ChipScope Proによるデバックの問題点)

The Simple MicroBlaze Microcontroller 16 (SDKのデバック)”でソフトウェアのデバックは終了したので、今度はハードウェアのデバックをするためにChipScope Pro(以下、ChipScope)を入れることにした。

SMM_Debug_cs.cdc を入れて、インプリメントしたところエラー発生。
SMM_62_101225.png

ERROR:Pack:2310 - Too many comps of type "BSCAN" found to fit this device.
ERROR:Pack:18 - The design is too large for the given device and package.
Please check the Design Summary section to see which resource requirement for
your design exceeds the resources available in the device.


結局、BSCANを2つ使っているとのことだった。ChipScopeでも使用するので、SMMで使用しているらしい。XPSで見るとDebug は有効になっていないのだが、BSCANが使われてしまうようだ。
SMM_63_101225.png

これを何とかしないと、ChipScopeが使えない。SMMから抜いてしまうのがベストなのだが、共用しても良い?方法を探ってみることにする。

どうやらSMMの状態でChipScopeを使う方法がわからないので、取り敢えずシミュレーションをすることにする。SMMでChipScopeを使えないとなると、使うのを考え直さなければならないかな?
このへんの情報を知っている方は教えてください。

(2010/12/25:追記)
SMM_noDBG_noUARTでやってみたが、なぜか?BSCANとMDM_coreが入っている?
SMM_64_101225.png
  1. 2010年12月25日 05:38 |
  2. SMM
  3. | トラックバック:0
  4. | コメント:0

VHDLによる乗算記述方法によるインプリメントの差異(Ver.12.3のXST)

ISE12.3のXSTを使って、VHDLによる乗算記述方法によるインプリメントの差異について調べてみた。使用デバイスはSpartan-6(xc6slx45t-3fgg484) (”VHDLによる乗算について(ISE12.3のXSTを使用)”と”Type Qualification とType Conversion”を参照)
まずは、”VHDLによる乗算について(ISE12.3のXSTを使用)”の(2010/12/21:追加)の掛け算のVHDLをXSTでインプリメントしてみた。(XSTの-use_dsp48オプションはAuto)

library IEEE;
use IEEE.std_logic_1164.all;
use ieee.std_logic_signed.all;
use ieee.std_logic_arith.all;

entity mult_test is
    port (
        clk : in std_logic;
        reset : in std_logic;
        ina : in std_logic_vector(7 downto 0);
        mult_out : out std_logic_vector(17 downto 0)
    );
end mult_test;

architecture RTL of mult_test is
signal mult : std_logic_vector(17 downto 0);
signal temp : std_logic_vector(8 downto 0);
begin
    temp <= "111110000";
    process(clk)
    begin
        if clk'event and clk='1' then
            if reset='1' then
                mult <= (others => '0');
            else
                mult <= unsigned(ina) * signed(temp);
            end if;
        end if;
    end process;
    mult_out <= mult;
end RTL;


インプリメントすると、DPA41A1がインスタンスされている (FPGA Editor)。
mult_8_101222.png

次に、下のVHDLソースでインプリメントしてみた。

library IEEE;
use IEEE.std_logic_1164.all;
use ieee.std_logic_signed.all;
use ieee.std_logic_arith.all;

entity mult_test is
    port (
        clk : in std_logic;
        reset : in std_logic;
        ina : in std_logic_vector(7 downto 0);
        mult_out : out std_logic_vector(17 downto 0)
    );
end mult_test;

architecture RTL of mult_test is
signal mult : std_logic_vector(17 downto 0);
begin
    process(clk) begin
        if clk'event and clk='1' then
            if reset='1' then
                mult <= (others => '0');
            else
                mult <= unsigned(ina) * signed'("111110000");
            end if;
        end if;
    end process;
    mult_out <= mult;
end RTL;



SLICEXとOLOGIC2でインスタンスされていて、DPS48A1は使用されていない。
mult_9_101222.png

同じ設定で、XSTの -use_dsp48をAutomaxに設定して、インプリメントしてみた。結果は、SLICEXとOLOGIC2でインスタンスされた。
XSTの -use_dsp48をYESに設定してみた。結果はDSP48A1を使用した。
このVHDLコードだと、XSTの -use_dsp48がYESの時だけ、DSP48A1を使用する。でも、XSTの -use_dsp48がYESだと、DPS48A1を使い切るとエラーになってしまう。

mult <= unsigned(ina) * signed'("111110000");



mult <= unsigned(ina) * signed(std_logic_vector'("111110000"));


に変更しても、同様の結果になった。

  1. 2010年12月22日 15:34 |
  2. VHDLの書き方
  3. | トラックバック:0
  4. | コメント:8

ISE12.4が出ています

ISE12.4が出てます
Xilinxからのメールによると、AMBA 4 AXI4 tool and IPのサポートが充実しているようです。やはり、AXI4サポート、Xilinxは本気なんでしょうか?
  1. 2010年12月22日 12:16 |
  2. Xilinx ISEについて
  3. | トラックバック:0
  4. | コメント:1

Type Qualification とType Conversion

VHDLのType Qualification とType Conversionについての覚書。(参考書籍、The Designer's Guide to VHDL, 2nd Editon, 48ページ)(リンクは3rd Editonです)

Type Qualification は、例えば
type STATE1 (idle, state1, state2);
type STATE2 (state2, idle, state1);
と宣言したときにSTATE1'(idle)、STATE2'(idle) と書ける。どっちの列挙宣言のidleかを指定できる。
std_logic_vector'("111110000")と書いたときは、string型がオーバーロードしていても、"111110000"がstd_logic_vector型であることを指定できる。

Type Conversionは、型を変換することができる。real(456), integer(32.57)
std_logic_vectorで宣言したsignalは、std_logic_signedライブラリをuseするか、std_logic_unsignedライブラリをuseするかでどちらの演算子を使うか指定できるようだ。でも足し算、引き算はどちらでも2進数の値は変わらない(2の補数表示)。ただ、比較演算子では、signedにはマイナスの数があるので、動作が変わることになる。掛け算では、符号拡張が行われる(signed)か、行われないか(unsigned)の違いがある。
signed(temp1), unsigned(temp2)

#間違っていたらコメントください。よろしくお願いします。
  1. 2010年12月22日 12:13 |
  2. VHDLの書き方
  3. | トラックバック:0
  4. | コメント:0

The Simple MicroBlaze Microcontroller 16 (SDKのデバック)

前回、main()関数の”Could not find the frame base for "main".”を修正したが、他の関数でも同じエラーが出ている。
SMM_61_101220.png

もう一度、Xilinxのアンサーデータベースを調べると、”12.1 EDK - SDK Error: Could not find frame base for ""”がヒット。それによると、stackエリアを増やせとのこと。早速、lscript.ldの記述を下のように変更した。

/* _STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x400; */
_STACK_SIZE = 0x1000;


これで、メモリの使用領域は、0x23c8から0x3010に増えた。

mb-size empty_application_0.elf  |tee "empty_application_0.elf.size"
   text       data        bss        dec        hex    filename
   6806        312       5186      12304       3010    empty_application_0.elf


これで、もう一度デバックモードにしてみたが同様にエラーが出る。
もうツールのデバックはいい加減にして、本来のCソースをデバックすることにした。大分いい感じで動いてはきてはいるのだが、まだおかしい。
SMM_62_101221.jpg

上のような表示になっていて、ロータリーエンコーダを右に回すと下の表示になる。
SMM_63_101221.jpg

ピンクで囲った0406の部分だが、本当は4060で上位桁、下位桁を間違っている。これはすぐ修正したが、他の状態遷移がまだおかしい。
#何をしているかというと、CMOSカメラの設定をLCDに表示して、ロータリーエンコーダで変更しようとしている。この辺を参照
  1. 2010年12月21日 05:01 |
  2. SMM
  3. | トラックバック:0
  4. | コメント:0

The Simple MicroBlaze Microcontroller 15 (デバック)

The Simple MicroBlaze Microcontroller 13 (16KB RAMのSMMでもう一度)”でソフトウェアをSDKでコンパイルできたので、今度はデバックを試みた。
デバックのやり方は”The Simple MicroBlaze Microcontroller 5(デバック機能)”を参照のこと。
デバックモードにすると、Consoleに”Could not find the frame base for "main".”と表示され、Variablesウインドウに変数値が表示されない。
SMM_58_101220.png

解決策を例によってXilinxのアンサーデータベースで検索したら、”12.1 EDK - SDK could not find the frame base for "main" in debugging”が引っかかった。
解決策としては、何のことはない、関数のプロトタイプ宣言をして、main関数を一番最初にしろとのことだった。

int func1(. . . ); //func1 prototype defined here

int main(void) //main defined here
{
:
:
}

int func1(. . . ) //func1 defined here
{
:
:
}


ソフトウェアを修正することにする。

int main(void)をCソースの一番上にして、下のインクルード・ファイルをインクルードした。

// lcd_rot_cont.h

void Timer_Wait (Xuint32 delay);
void lcd_init (void);
void lcd_print (Xuint32 Line, Xuint8 *Str);
void lcd_clear (void);
void timer_int_handler(void * arg);
void SCCB_reg_init(void);
char *ntoxn(char *str, unsigned short int x, int n);
char *strcpyc(char *s1, char *s2);
void SCCB_reg_status_disp(Xuint8 *Str);
void SCCB_cur_reg_disp(Xuint8 *Str);
void gain_level_reg_set(void);
void aec_level_h_reg_set(void);
void aec_level_l_reg_set(void);
int main(void);


すると、エラーが無くなって、変数が表示されるようになった。
SMM_60_101220.png
  1. 2010年12月20日 05:50 |
  2. SMM
  3. | トラックバック:0
  4. | コメント:0

最後の忠臣蔵(映画)を見てきました

今日は最後の忠臣蔵を見てきた。人間の生き様を感じさせる映画。良いか悪いかは別問題として。。。見て良かったと思う。
やはり武士は武士なんだろう?多分。
嫁入りシーンでは感動したが、最後は冷静に見ていた。最後のシーンで考えたことは、人にはそれぞれに生きて行く上でこだわりがあって、他の人にはわからないかもしれない?ということ。私がいろいろFPGAの事をやっているのを、一般の人が見たら、この武士を見ている自分と同じように思うのかもしれない。
  1. 2010年12月20日 05:02 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:0

スリッパ入れ完成

ほぞ溝結合で作っていたスリッパ入れですが、土曜日にワトコのミディアムウォルナットで塗装しました。この素材はかなりオイルを吸い込んで、1回塗りで十分な色になりました。前回の引き戸は3度塗したのですが、スリッパ入れの方が色が濃いです。引き戸は赤松集成材。スリッパ入れはパイン集成材だと思います。
下の写真を見るとわかりますが、2段目の真ん中辺りに白いところがありますが、これは集成材の接着剤が着きすぎているところです。この集成材は安かったのですが、B級品のようです。オイルフィニッシュ仕上げの場合はやはりA級品を使ったほうが良いですね。右はじの接合部が白くなっているのは、接着剤のふき漏れです。接着後によく拭かないとこうなります。次からはよく拭くようにします(反省点)。
slipper_4_101220.jpg
  1. 2010年12月20日 04:32 |
  2. 木工
  3. | トラックバック:0
  4. | コメント:0

The Simple MicroBlaze Microcontroller 13 (16KB RAMのSMMでもう一度)

The Simple MicroBlaze Microcontroller 12 (XPSでSMMをカスタマイズ)”でRAMを16KBに拡張したはずなので、生成したsmm.ngcとsmm.bmmをISE12.3のプロジェクトに入れてインプリメントし、SDKでコンパイルしてみた。

前回のプロジェクトにsmm.ngcとsmm_sutb.bmmからリネームしたsmm.bmmを入れて、もう一度インプリメントした。すると、Translateでエラー発生。よく見たら、bmmファイルのインスタンスパスが違っていた。一階層深くなっているので、bmmファイルを編集して、lcd_rot_cont_inst/ を追加した(前回同じことをやっていたのに懲りない。smm.ngcを置く階層に応じてsmm.bmmファイル階層表示を書き換える必要がある)。
こうしたらインプリメントが通った。FPGA Editorで見ても、SMMのRAMのインスタンスは8個あった。

次に、sdk3フォルダを新規に作成して、smm.xmlを置く。”The Simple MicroBlaze Microcontroller 4(リファレンスデザイン2)”の手順でSDKの設定をした。lcd_rot_cont.c をSDKのsrc フォルダにドラック&ドロップする。ビルドが始まり正常終了した。やったー。。。0x23c8番地まで使っているようなので、やはり8KBでは足りなかったようだ。下にビルド・メッセージを示す。

**** Build of configuration Debug for project empty_application_0 ****

make all 
Building file: ../src/lcd_rot_cont.c
Invoking: MicroBlaze gcc compiler
mb-gcc -Wall -O0 -g3 -c -fmessage-length=0 -I../../empty_application_bsp_0/microblaze_0/include -mcpu=v7.30.a -mno-xl-soft-mul -MMD -MP -MF"src/lcd_rot_cont.d" -MT"src/lcd_rot_cont.d" -o"src/lcd_rot_cont.o" "../src/lcd_rot_cont.c"
Finished building: ../src/lcd_rot_cont.c
 
Building target: empty_application_0.elf
Invoking: MicroBlaze gcc linker
mb-gcc -Wl,-T -Wl,../src/lscript.ld -L../../empty_application_bsp_0/microblaze_0/lib -mcpu=v7.30.a -mno-xl-soft-mul -o"empty_application_0.elf"  ./src/lcd_rot_cont.o   
Finished building target: empty_application_0.elf
 
Invoking: MicroBlaze Print Size
mb-size empty_application_0.elf  |tee "empty_application_0.elf.size"
   text       data        bss        dec        hex    filename
   6730        312       2118       9160       23c8    empty_application_0.elf
Finished building: empty_application_0.elf.size
 
Invoking: Xilinx ELF Check
elfcheck empty_application_0.elf -hw ../../SMM_DBG_noUART_hw_platform/system.xml -pe microblaze_0  |tee "empty_application_0.elf.elfcheck"
elfcheck
Xilinx EDK 12.3 Build EDK_MS3.70d
Copyright (c) 1995-2010 Xilinx, Inc.  All rights reserved.

Command Line: elfcheck -hw ../../SMM_DBG_noUART_hw_platform/system.xml -pe
microblaze_0 empty_application_0.elf 

ELF file    : empty_application_0.elf
elfcheck passed.
Finished building: empty_application_0.elf.elfcheck


SDKのXilinx ToolsメニューからProgram FPGAを選択して、ダウンロードしてみたが、動作がおかしい。デバックする必要がある。やっと、ソフトウェアのデバックの段階まで来た。
  1. 2010年12月18日 18:51 |
  2. SMM
  3. | トラックバック:0
  4. | コメント:0

The Simple MicroBlaze Microcontroller 12 (XPSでSMMをカスタマイズ)

前回、SMMのRAM容量が足りないなそう?ということがわかったので、XPSでSMMをカスタマイズし、RAMを8KBから16KBへ倍増させてみることにした。(最初は12.3でやったのだがワーニングが出ていて良いかどうかわからなくなったので、12.1でやり直した)

1. 最初にSMMのフォルダのうちで、SMM_Srcにソースが入っているので、そのうちのS3 (Spartan-3A) フォルダの下のSMM_DBG_noUARTフォルダを適当なフォルダの下にコピーする。ここでは、SMM_S3_BRAM_16Kフォルダの下にコピーする。

2. StartメニューからISE12.3のXilinx Platform Studio(XPS)を立ち上げ、Xilinx Platform StudioのダイアログでOpen recset project を選択し、OKボタンをクリックする。
SMM_43_101217.png

3. Open Existing Projectダイアログで1.のSMM_DBG_noUARTフォルダの下のsmm.xmpを選択して、Openボタンをクリックする。
SMM_44_101217.png

4. プロジェクトを作ったバーションと違うので、プロジェクトを変換するというダイアログが出たので、OKボタンをクリックした。プロジェクトが変換するために、Version Management Wizard が立ち上げる。Next ->ボタンをクリックする。(結構先が長いのかな?やりながらブログを書いています)
SMM_45_101217.png

5. bram_blockがアップデートしたけどfully backward compatible だそうだ。(それなら自動的にアップデートしても良さそう。。。)
SMM_47_101217.png

6. 次はplb_v46。1.04.aから1.05aに変更になったようだ。これは、ピンとパラメターはbackward compatible だが、他の機能が変更されているそうなので、Updata?のチェックを外した。(選べるのも便利そうだ。。。)
SMM_48_101217.png

7. 次はnot backward compatibleで、manually upgrade とのことだ。どうしよう?
SMM_49_101217.png

8. Apply Changes to your Project で終了。不安が残るが、Finishをクリックする。(だめならばやり直す)
SMM_50_101217.png

9. XPSが立ち上げる。やはり、ところどころ黄色い!が付いている。
SMM_51_101217.png

10. dlmb_cntlrのlmb_bram_if_cntlrをダブルクリックして、ダイアログを表示させる。LMB BRAM High Addressを0x00001fffから0x00003fffに変更する。
SMM_52_101217.png

11. ilmb_cntlrのlmb_bram_if_cntlrもダブルクリックして、ダイアログを表示させる。LMB BRAM High Addressを0x00001fffから0x00003fffに変更する。

12. ProjectメニューからExport Hardware Design to SDK...を選択する。
SMM_53_101217.png

13. Export to SDK/Launch SDKダイアログが開く。Include bitstream and BMM fileにチェックを入れるかどうか迷ったが、チェックを入れないと、smm.xmlは生成されるが、smm.ngcとsmm.bmmは生成されないようだ。Export Onlyボタンをクリックする。
SMM_54_101217.png

14. そうするとエラーが出てしまう。ワーニングが出ているせいかな?といろいろやってみたのだが、おかしくなってしまった。ここで諦めて、バージョン12.1のXPSでやり直した。こっちは、すんなりXPSが開いてワーニングがない。
SMM_56_101217.png

15. 12.3同様にdlmb_cntlrとilmb_cntlrのLMB BRAM High Addressを0x00001fffから0x00003fffに変更して、12.と13.を行う。

16. するとやはり同じようなエラーが出てしまう。

--------------
Number of errors : 87
Number of warnings : 91
ERROR:Xflow - Program map returned error code 2. Aborting flow execution...
Done!


17. しかし、smm.ngc, smm.bmm, smm.xml は出来ているようなので、このまま使うことにする。多分、12.3でも出来ていたので、12.3でも大丈夫だと思う?

smm.ngc : SMM_S3_BRAM_16K\SMM_DBG_noUART\implementation\smm.ngc
smm.bmm : SMM_S3_BRAM_16K\SMM_DBG_noUART\implementation\smm_stub.ngc
smm.xml : SMM_S3_BRAM_16K\SMM_DBG_noUART\SDK\SDK_Export\hw\smm.xml


smm.bmmを開いてみてみたが、以前はBRAMのインスタンスが4個で8KBだったが、8個になっていたので、メモリは16KBになったと思う。
  1. 2010年12月18日 13:30 |
  2. SMM
  3. | トラックバック:0
  4. | コメント:0

VHDLによる乗算について(ISE12.3のXSTを使用)

VHDLで乗算記号*を使ったときに、どのようになるのかが、よくわからなかったので試してみた。その覚書です。特にunsigned とsignedを掛けたときにどうなるのか?std_logic_vector同士をそのまま掛けたらsignedとして扱ってくれるのか?よくわからなかった。

さて早速試してみたい。まずはテストベンチから示す。これは変更することがないので、最初に示す。

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
 
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;
 
ENTITY mult_test_tb IS
END mult_test_tb;
 
ARCHITECTURE behavior OF mult_test_tb IS 
 
    -- Component Declaration for the Unit Under Test (UUT)
 
    COMPONENT mult_test
    PORT(
         clk : IN  std_logic;
         reset : IN  std_logic;
         ina : IN  std_logic_vector(8 downto 0);
         inb : IN  std_logic_vector(8 downto 0);
         mult_out : OUT  std_logic_vector(17 downto 0)
        );
    END COMPONENT;
    

   --Inputs
   signal clk : std_logic := '0';
   signal reset : std_logic := '0';
   signal ina : std_logic_vector(8 downto 0) := (others => '0');
   signal inb : std_logic_vector(8 downto 0) := (others => '0');

     --Outputs
   signal mult_out : std_logic_vector(17 downto 0);

   -- Clock period definitions
   constant clk_period : time := 10 ns;
 
BEGIN
 
    -- Instantiate the Unit Under Test (UUT)
   uut: mult_test PORT MAP (
          clk => clk,
          reset => reset,
          ina => ina,
          inb => inb,
          mult_out => mult_out
        );

   -- Clock process definitions
   clk_process :process
   begin
        clk <= '0';
        wait for clk_period/2;
        clk <= '1';
        wait for clk_period/2;
   end process;
 

   -- Stimulus process
   stim_proc: process
   begin        
      -- hold reset state for 100 ns.
        reset <= '1';
      wait for 100 ns;    
        reset <= '0';
      wait for clk_period*10;

      -- insert stimulus here 
        ina <= "000000010";
        inb <= "000000011";
        
        wait for 450 ns;
        
        ina <= "000000011";
        inb <= "111111111";

      wait;
   end process;

END;


最初に2と3を掛ける。次にsignedだったら3と-1を掛けている。
最初は、ただ単にinaとinbを掛ける。

-- mult test

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

entity mult_test is
    port (
        clk : in std_logic;
        reset : in std_logic;
        ina : in std_logic_vector(8 downto 0);
        inb : in std_logic_vector(8 downto 0);
        mult_out : out std_logic_vector(17 downto 0)
    );
end mult_test;

architecture RTL of mult_test is
begin
    process(clk)
    begin
        if clk'event and clk='1' then
            if reset='1' then
                mult_out <= (others => '0');
            else
                mult_out <= ina * inb;
            end if;
        end if;
    end process;
end RTL;


シミュレーションをした結果を下に示す。
mult_1_101217.png

2*3=6(110)は良いとして、3*(-1)は、unsignedとして演算されているようだ。これは、ライブラリに”use ieee.std_logic_unsigned.all”をしているので当然かも知れない? ”use ieee.std_logic_signed.all”に書き換えたときのシミュレーション結果を下に示す。
mult_2_101217.png

2*3=6(110)は当然同じだが、3*(-1)は2の補数表示で-3になっている。
次にxc6slx45t-3fgg484でインプリメントしてみた。Spartan-6のLX45Tだ。
最初に、ライブラリが”use ieee.std_logic_unsigned.all”の方から、DSP48に掛け算が割り当てられている。DSP48の入力ピンを下に示す。
mult_3_101217.png

ina, inbとも9ビット目まで入力ピンが入っていて、その他はGNDになっている。

次に、ライブラリが”use ieee.std_logic_signed.all”のとき。
やはり、DSP48に掛け算が割り当てられている。DSP48の入力ピンを下に示す。
mult_4_101217.png

ina, inbとも9ビット目までは、unsignedの時と同じだが、10ビット目以降は、GNDではなく、それぞれの9ビット目のピンに接続されている。符号拡張が行われている。

ちなみに出来れば、inaはunsignedで、inbはsignedだと一番都合が良いのだが。。。それでやってみた。
ライブラリが”use ieee.std_logic_signed.all”のときに、掛け算の気球つ部分を以下の式に取り替えた。

mult_out <= unsigned(ina) * signed(inb);


最初に、シミュレーションをしてみた。
mult_5_101217.png

完全に値がおかしい。
インプリメントすると下のエラーが出た。

ERROR:HDLCompiler:410 - "\HDL\FndISEWork\DWM2008_07\Graphic_board2\test\mult_test\Synth123\../mult_test.vhd" Line 32: Expression has 19 elements ; expected 18


19ビットにしないとダメみたいだ。ということはunsignedの方に1ビット付け足すのかな?
今まで9ビット長だったinaをすべて8ビット長にして確かめてみたところ(inbは9ビット長)、シミュレーションは正常になった。
mult_6_101217.png

インプリメントした結果のDSP48のピン割り当てを下に示す。
mult_7_101217.png

unsignedのinaは8ビット目までDSP48のピンに割り当てられていて、それ以上はGNDに接続されている。signedのinbは9ビット目まで割り当てられていて、それ以上はすべてinbの9ビット目に接続されている(符号拡張)。
これで目的は果たすことができそうだ。

更にintegerで書いてみた。

    process(clk)
        variable i, j, k : integer := 0;
    begin
        if clk'event and clk='1' then
            if reset='1' then
                mult_out <= (others => '0');
            else
                i := CONV_INTEGER(unsigned(ina));
                j := CONV_INTEGER(signed(inb));
                k := i * j;
                mult_out <= CONV_STD_LOGIC_VECTOR(k, 18);
            end if;
        end if;
    end process;


シミュレーションもインプリメントも”mult_out <= unsigned(ina) * signed(inb);”と同じで正常だった。

(2010/12/21:追加)
片方が定数の場合は、下の式ではエラーだった。

mult <= unsigned(ina) * signed("111110000");


std_logic_vectorのsignalを宣言して、それに代入してからsignedでキャストする。

signal temp : std_logic_vector(8 downto 0);
begin
    temp <= "111110000";
    process(clk) begin
        if clk'event and clk='1' then
            if reset='1' then
                mult <= (others => '0');
            else
                mult <= unsigned(ina) * signed(temp);
            end if;
        end if;
    end process;

  1. 2010年12月17日 15:58 |
  2. VHDLの書き方
  3. | トラックバック:0
  4. | コメント:4

The Simple MicroBlaze Microcontroller 11(SDKでエラー発生)

SMMでCMOSカメラのパラメータを設定するために、LCDにパラメータを表示して設定するという計画(長い。。。)のCソースは、だいたい書き終えた。550行くらいあるので、ソースをブログに貼ることができない。長い。
SDKでビルドしようとしたらエラーになってしまった。エラーは下の通り。

../../empty_application_bsp_0/microblaze_0/lib/libxil.a(write.o): In function `write':
/gnu/mb_gnu/src/gcc/libgloss/microblaze/write.c:36: undefined reference to `outbyte'
/gnu/mb_gnu/src/gcc/libgloss/microblaze/write.c:34: undefined reference to `outbyte'
../../empty_application_bsp_0/microblaze_0/lib/libxil.a(read.o): In function `read':
/gnu/mb_gnu/src/gcc/libgloss/microblaze/read.c:35: undefined reference to `inbyte'


SMM_41_101215.png

早速、おなじみのXilinxのアンサーをあさると、”32968 - 11.1 EDK - GCC コンパイラで undefined reference to "outbyte" エラーが発生する”が見つかった。ソリューションを下に引用する。

このエラーは、[Software Platform Settings] で stdout が None に設定されているのに print 関数で有効な stdout が必要になるために発生します。
[Software] > [Software Platform Settings] > [OS and Libraries] で有効な stdout を設定してライブラリを生成し直すとこの問題を解決できます。


あれ?これはよくみるとXPSでの解決策だった。SDKはSoftwareメニューがない。。。どうしたら良いのか?
stdio.hをインクルードして、sprintfを使っているのが多分まずいんだろうと思う?

    switch (setting_item) {
        case AGC_SET :
            if (agc_reg)
                i = sprintf((char *)Str, "AGC ON");
            else
                i = sprintf((char *)Str, "AGC OFF");
            break;
        case GAIN_LEVEL_SET :
            i = sprintf((char *)Str, "AGC GAIN %03x", gain_level);
            break;


UG643 OS and Libraries Document Collectionの76ページのTable16: Configuration Parameterの stdin, stdoutをnoneから何か選べれば大丈夫だと思うのだが、その方法がわからない?やはりXPSを使う必要があるのかな?

あれ?もしかしたら、現在はSMM_DEG_noUART_hw_platformを使っているが、これではstdin, stdoutを使うにしてもどこにつないだら良いのだろう?となってしまうのではないか?使わないまでもUARTがあるのを選べば、stdin, stdoutがUARTになっているということはないだろうか?

SMM_Fullつまり、DEBUGもUARTも入ってる物をSDKで読み込んだら、Board Supprot Package Settings のところでstdin, stdout がUART になっていた。これでやればCソースをコンパイルできるかな?
SMM_42_101215.png

やってみたところ、今度は undefined reference to `outbyte'などのエラーは出なくなったので、stdin, stdoutの問題はクリアされているようだが、どうやら8KBのRAMが一杯になってしまったのかな?

/cygdrive/k/HDL/Xilinx/12.3/ISE_DS/EDK/gnu/microblaze/nt/bin/../lib/gcc/microblaze-xilinx-elf/4.1.2/../../../../microblaze-xilinx-elf/bin/ld: region ilmb_cntlr_dlmb_cntlr is full (empty_application_0.elf section .text)
/cygdrive/k/HDL/Xilinx/12.3/ISE_DS/EDK/gnu/microblaze/nt/bin/../lib/gcc/microblaze-xilinx-elf/4.1.2/../../../../microblaze-xilinx-elf/bin/ld: empty_application_0.elf: section .text lma 0x50 overlaps previous sections
/cygdrive/k/HDL/Xilinx/12.3/ISE_DS/EDK/gnu/microblaze/nt/bin/../lib/gcc/microblaze-xilinx-elf/4.1.2/../../../../microblaze-xilinx-elf/bin/ld: empty_application_0.elf: section .fini lma 0x78 overlaps previous sections
/cygdrive/k/HDL/Xilinx/12.3/ISE_DS/EDK/gnu/microblaze/nt/bin/../lib/gcc/microblaze-xilinx-elf/4.1.2/../../../../microblaze-xilinx-elf/bin/ld: empty_application_0.elf: section .rodata lma 0x98 overlaps previous sections
/cygdrive/k/HDL/Xilinx/12.3/ISE_DS/EDK/gnu/microblaze/nt/bin/../lib/gcc/microblaze-xilinx-elf/4.1.2/m/crtend.o:(.init+0x0): relocation truncated to fit: R_MICROBLAZE_32_PCREL_LO against `.text'
collect2: ld returned 1 exit status
make: *** [empty_application_0.elf] Error 1


メモリの量が足りないとしたら、やはり、stdioのライブラリを呼んでしまったので、ライブラリ分だけ増えちゃったんだろうな?
どうしようか?sprintfを使わないで、独自に関数を書いちゃおうか?そうしてみます。

(2010/12/16:追加)
sprintfを独自関数で書きなおしても

/cygdrive/k/HDL/Xilinx/12.3/ISE_DS/EDK/gnu/microblaze/nt/bin/../lib/gcc/microblaze-xilinx-elf/4.1.2/../../../../microblaze-xilinx-elf/bin/ld: region ilmb_cntlr_dlmb_cntlr is full (empty_application_0.elf section .heap)


になってしまった。
こうなったら、SMMをXPSで、リコンフィグして、メモリを8Kから16Kに変更しようと思う。
  1. 2010年12月15日 05:04 |
  2. SMM
  3. | トラックバック:0
  4. | コメント:0

日記 (2010/12/12)

日曜日はFPGA-CAFEに行ってきました。すすたわりさんといろいろ打ち合わせ、yuna_digickさんやcronos_svさんや色々な方とお話できて、というか基板の話は基板を作ったことがないので、聞いているばかりでしたが、聞いていると為になります。いつから自分で基板を設計してみたいです。
自宅では、OV7670、CMOSカメラの設定をSMMでやらせようとCソースを書いています。結構長くなっています。なかなか終りませんね。頑張って書こうと思っています。後、4割くらいかな?
日曜日の午前中は、技術論文の締切りが迫っているので、職場に行って書いていました。だいたい書き終わったので、修正です。
  1. 2010年12月13日 05:58 |
  2. その他のFPGAの話題
  3. | トラックバック:0
  4. | コメント:0

スリッパ入れの製作

この前からだけど、スリッパ入れを作っています。今回はほぞ、みぞ組にしました。材料は多分パイン集成材の20mm厚を使いました。
みぞはモチロンのこと、ほぞもトリマーで作りました。まずはみぞから、直径12mmのストレートビットをトリマーに付けて、11mm程度の深さのみぞを掘りました。最初から11mm掘るのではなく、4mm、7mmと3回に分けてみぞを掘りました。
slipper_1_101211.jpg

端は丸くなるので、のみで掘っていたのですが、もう少し、トリマーで掘るようにしました。その分のみぞは板に隠れて見えません。
次にほぞを掘りました。ほぞは板の端から10mm程度の幅で、4mm掘りました。縦のところはのみで掘りました。ほぞの厚みは12mmです。
slipper_2_101211.jpg

ボンドを付けて組み合わせて、クランプで止めました。
slipper_3_101211.jpg

明日の朝まで、このままにします。
初めての、ほぞ、みぞ接合でしたが、トリマーでほぞを彫り出すと、掘り出した端を平にするのは、難しいですね。特に最後にトリマーが抜けるところが削り過ぎちゃいます。反省点がわかりました。
ほぞ、みぞ接合は難しいけど、コーススレッドを打った穴が見えないところが良いですね。もう少し精進したいと思います。
  1. 2010年12月11日 20:43 |
  2. 木工
  3. | トラックバック:0
  4. | コメント:0

The Simple MicroBlaze Microcontroller 10 (Cソフトウェアを書いているところ)

前回、SCCBレジスタの設定回路(SCCBインターフェース回路)をSMMから制御できるようにハードウェアを変更と、LCDに表示して設定するSCCBレジスタを決定したので、今度はSDKのソフトウェアを変更中だ。
今のところ、SCCB設定用レジスタの設定用のdefineを書いている。まだ全部書けていないが、下のような感じで書いている。

#define    SCCB_REG_00        0x00    // SCCB Register Address 0x00 (GAIN[7:0])
#define SCCB_REG_01        0x40    // SCCB Register Address 0x01 (AWB RED)
#define SCCB_REG_02        0x60    // SCCB Register Address 0x02 (AWB BLUE)
#define SCCB_REG_03        0x0A    // SCCB Register Address 0x03 ([7:6] - GAIN LEVEL[9:8])
#define SCCB_REG_04        0x00    // SCCB Register Address 0x04 ([1:0] - AEC LEVEL L[1:0])
#define SCCB_REG_07        0x00    // SCCB Register Address 0x07 ([5:0] - AEC LVEVL H[7:2])
#define    SCCB_REG_10        0x00    // SCCB Register Address 0x10 ([5:0] - AEC LEVEL L[7:2])
#define SCCB_REG_13        0xEF    // SCCB Register Address 0x13 ([2] - AGC, [1] - AWB, [0] - AEC)
#define SCCB_REG_1E        0x27    // SCCB Register Address 0x1E ([5] - MIRROR)

#define awb_red            reg01
#define    awb_blue        reg02

#define SCCB_2_AGC            ((reg13 & 0x04)>>2)
#define AGC_2_SCCB            ((agc_reg & 0x01)<<2)
#define SCCB_2_AWB            ((reg13 & 0x02)>>1)
#define AWB_2_SCCB            ((awb_reg & 0x01)<<1)
#define SCCB_2_AEC            (reg13 & 0x1)
#define AEC_2_SCCB            (aec_reg & 0x01)
#define    SCCB_2_GAIN_LEVEL    (((reg03 & 0xC0)<<2) | reg00)
#define GAIN_LEVEL_2_SCCB03    ((gain_level & 0x300)>>2)
#define GAIN_LEVEL_2_SCCB00    (gain_level & 0xFF)


/* Global Variable */
// SCCB Register Variable
unsigned char reg00 = SCCB_REG_00;
unsigned char reg01 = SCCB_REG_01;
unsigned char reg02 = SCCB_REG_02;
unsigned char reg03 = SCCB_REG_03;
unsigned char reg04 = SCCB_REG_04;
unsigned char reg07 = SCCB_REG_07;
unsigned char reg10 = SCCB_REG_10;
unsigned char reg13 = SCCB_REG_13;
unsigned char reg1E = SCCB_REG_1E;

unsigned char agc_reg;
unsigned short int gain_level;
unsigned char awb_reg;
unsigned char aec_reg;
unsigned char aec_level_h;
unsigned char aec_level_l;
unsigned char mirror_reg;


作っているが、書いていると飽きてくる。。。が、取り敢えず、マクロを作りきる。

#C++本格的に書いたことが無いので、よくわからないが、C++だったらSCCBレジスタを設定するクラスとかを作って、それを継承して個別のレジスタを設定するメソッドを書けば良いのだろうか?
  1. 2010年12月10日 05:39 |
  2. SMM
  3. | トラックバック:0
  4. | コメント:2

The Simple MicroBlaze Microcontroller 9 (SCCB回路の変更、設定SCCBレジスタ)

さて、前回でロータリーエンコーダを使用することができた
今度は、SCCBレジスタの設定回路(SCCBインターフェース回路)をSMMから制御できるようにハードウェアを変更することと、LCDに表示して設定するSCCBレジスタを決定した。設定するSCCBレジスタの決定には、特殊電子回路株式会社の”OV7670で作るUSBカメラ”のページを参考にさせて頂いた。
最初に設定するレジスタの仕様を下に示す。
SMM_40_101209.png

AGC、AWB、AECのON, OFFと値、MIRRORのON, OFFを設定できるようにした。LCDの1桁目は設定する項目 (AGC, AWBなど)の値を表示する。ロータリーエンコーダのセンタースイッチを押すと編集モードに入って、1行目の後ろにEを表示する。編集モードでは、表示されている項目のON, OFFまたは値をロータリーエンコーダの右、または左回転で変更することができる。もう一度ロータリーエンコーダのセンタースイッチを押すと、編集モードから抜けて表示モードに戻る。この時に、ロータリーエンコーダの右、または左回転すると、表示する項目を移動できる。
LCDの2桁目は、全体を上図のように表示する。GはAGCがONであることを示し、BはAWBがONであること、EはAECがONであること、MはMIRRORがONであることを示す。OFFの時には表示は消える。

次に、SCCBインターフェース回路の変更点だ。
SCCBインターフェース回路の説明は、”SCCBインターフェース回路の説明1(SCCB_Reg_Controller.vhd)”、”SCCBインターフェース回路の説明2(freqdiv.vhd、SCCB_reg_values_ROM.vhd)”、”SCCBインターフェース回路の説明3(One_Transaction_SCCB.vhd)”を参照してください。
この中のSCCB_Reg_Controller.vhd にaddr_data、ad_enable、SCCB_busy の3つのポートを追加した。addr_dataは全体で16ビットで、上位8ビットがアドレス、下位8ビットがデータとなる。ad_enableはaddr_dataの値が有効でSCCBレジスタへの書き込みを示す1パルスの信号だ。SCCB_busyは、現在ステートマシンがSCCBレジスタに書き込み中を示す。これは、ステータス信号として、SMM (The Simple MicroBlaze Microcontroller) からReadすることができるようにする。

entity SCCB_Reg_Controller is
    port(
        clk : in std_logic; -- クロック
        reset  : in std_logic; -- リセット
        addr_data : in std_logic_vector(15 downto 0); -- SMMから設定されるSCCB設定レジスタのアドレスとデータ
        ad_enable : in std_logic; -- addr_data信号のイネーブルパルス
        SCCB_busy : out std_logic; -- SCCBレジスタを設定中を表すbusyフラグ
        SCL : out std_logic; -- SCCBのクロック
        SDA : out std_logic -- SCCBのデータ
    );
end SCCB_Reg_Controller;


初期化時に、SCCBインターフェース回路は、SCCB_reg_values.data の設定値を全て設定するが、その後はSMMの要求で、SCCBレジスタに設定値を書きこむように変更した。初期化設定時には、SCCB_busyを1にしておいて、SMMにSCCBインターフェース回路がbusyであることを知らせる。初期化後はaddr_data、ad_enableによるSMMからのレジスタ書き込みを行うことができるが、SMMはその前にSCCB_busyフラグを読んで、SCCBインターフェース回路がbusyでないことを確かめてから、レジスタの設定を行う。
下にSCCB_Reg_Controller.vhd の変更箇所を示す。

    -- One_Transaction_SCCB のインスタンス
    One_Transaction_SCCB_inst : One_Transaction_SCCB port map(
        clk => clk,
        reset => reset,
        SCCB_address => SCCB_address,
        SCCB_data => SCCB_data,
        op_enable => op_enable,
        start_pulse => SCCB_start_pulse,
        end_pulse => end_pulse,
        SCL => SCL,
        SDA => SDA
    );
    -- セレクタ、初期化が終了するまではROMのデータを選択して、終了した後ではSMMからの設定を選択する
    SCCB_address <= ROM_data(15 downto 8) when cs_reg_set/=end_state else addr_data(15 downto 8);
    SCCB_data <= ROM_data(7 downto 0) when cs_reg_set/=end_state else addr_data(7 downto 0);
    SCCB_start_pulse <= start_pulse when cs_reg_set/=end_state else ad_enable;
    
    -- SCCB_busyの制御
    process(clk) begin
        if clk'event and clk='1' then
            if reset='1' then
                cs_SCCB_busy <= idle_SCCB_busy;
                SCCB_busy_node <= '1';
            else
                case cs_SCCB_busy is
                    when idle_SCCB_busy =>
                        if cs_reg_set=end_state then -- 初期設定が終了
                            cs_SCCB_busy <= initialize_end;
                            SCCB_busy_node <= '0';
                        end if;
                    when initialize_end =>
                        if ad_enable='1' then -- SMMのSCCBレジスタ設定開始
                            cs_SCCB_busy <= SCCB_setting;
                            SCCB_busy_node <= '1';
                        end if;
                    when SCCB_setting =>
                        if end_pulse='1' then -- SMMのSCCBレジスタ設定終了
                            cs_SCCB_busy <= initialize_end;
                            SCCB_busy_node <= '0';
                        end if;
                end case;
            end if;
        end if;
    end process;
    SCCB_busy <= SCCB_busy_node;


ここで、cs_reg_setはステートマシンのステートを示す信号で、end_stateに遷移していると初期化が終了したことを示している。

次に、SMMとのインターフェース回路lcd_rot_cont.vhdだが、ここにSCCB_addr_data、SCCB_ad_enable、SCCB_busyポートを追加した。

entity lcd_rot_cont is
    Port (     clk : in  STD_LOGIC;
                Reset : in  STD_LOGIC;
                rot_a : in std_logic;
                rot_b : in std_logic;
                rot_center : in std_logic;
                Button_S : in STD_LOGIC;
                LCD_DB : out STD_LOGIC_VECTOR (7 downto 0);
                LCD_RS : out STD_LOGIC;
                LCD_RW : out STD_LOGIC;
                LCD_E : out STD_LOGIC;
                SCCB_addr_data : out std_logic_vector(15 downto 0); -- SMMから設定されるSCCB設定レジスタのアドレスとデータ
                SCCB_ad_enable : out std_logic; -- addr_data信号のイネーブルパルス
                SCCB_busy : in std_logic -- SCCBレジスタを設定中を表すbusyフラグ
    );
end lcd_rot_cont;


0040番地にSCCBインターフェース回路へのアドレス、データを書き込む回路を追加した。

CS_SCCB_wr <= '1' when ((ADDR = X"0040") and CS = '1' and RNW = '0') else '0' ;


SCCB_ad_enableを生成する回路を追加して、アドレス、データの16ビットは下位16ビットに割り当てた。

    -- SCCB_ad_enable の生成
    process(clk) begin
        if clk'event and clk='1' then
            if Reset='1' then
                SCCB_ad_enable <= '0';
            else
                if CS_SCCB_wr='1' and CS_SCCB_wr_1d='0' then
                    SCCB_ad_enable <= '1';
                else
                    SCCB_ad_enable <= '0';
                end if;
            end if;
        end if;
    end process;
    
    SCCB_addr_data <= DOUT(0 to 15);  -- 上位16ビット


(修正)
SCCB_addr_data <= DOUT(0 to 15); -- 上位16ビット に修正しました。元は下位16ビットでした。アドレスが面倒になるので上位16ビットに変更です。
  1. 2010年12月09日 05:12 |
  2. SMM
  3. | トラックバック:0
  4. | コメント:0

The Simple MicroBlaze Microcontroller 8 (ロータリーエンコーダの実装)

前回の”The Simple MicroBlaze Microcontroller 7 (50MHzから25MHzへクロックを変更)”でクロック周波数を50MHzから25MHzに変更してみたが、今度は目的の”Spartan-3A Starter Kitによる画像演奏装置”にロータリーエンコーダの制御回路と一緒に組み込んだ。だが、まだ、目的のSCCB設定レジスタを制御するように変更してはいない。それは今、修正中だ。

さて、ロータリーエンコーダをled_ref.vhdの中に下のように組み込んだ。ついでに、いつまでもled_ref.vhdではないので、ファイル名もlcd_rot_cont.vhdに変更した。(ついでにCのソフトウェアのファイル名もlcd_rot_cont.cに変更した)

    -- ロータリーエンコーダ
    rot_enc_cont_i : rot_enc_cont port map(
        clk => clk,
        reset => Reset,
        rot_a => rot_a,
        rot_b => rot_b,
        rot_center => rot_center,
        right_pulse => right_pulse,
        left_pulse => left_pulse,
        center_pulse => center_pulse
    );


SMMのDIN入力は下のように変更した。

DIN (0) <= Button_S_int;
DIN (1) <= right_pulse;
DIN (2) <= left_pulse;
DIN (3) <= rot_center;
DIN (4 to 31) <= (others => '0') ; -- Not used


更に、ロータリーエンコーダのセンタースイッチを押すと、LCDにrot_center と表示するように、SMMのソフトウェアを変更した。同様にロータリーエンコーダを右に回すとright_pulse、左に回すとleft_pulseと表示するようにした。そうすると、ロータリーエンコーダのセンタースイッチは反応して、LCDにrot_center と表示されるが、他は表示されない。
そうだ、pulseは1パルスのみ出力するんだった。これではSMMが検知できないということでハンドシェークすることにした。どうしたかというと、right_pulse, left_pulse をホールドするFF (right_hold, left_hold) を付けて、それらをクリアする書き込みアドレスを用意した。

    -- right_pulse, left_pulse をホールドするFF
    process(clk) begin
        if clk'event and clk='1' then
            if Reset='1' then
                right_hold <= '0';
                left_hold <= '0';
            else
                if right_pulse = '1' then
                    right_hold <= '1';
                elsif CS_rot_enc_wr='1' then 
                    right_hold <= '0';
                end if;
                
                if left_pulse='1' then
                    left_hold <= '1';
                elsif CS_rot_enc_wr='1' then
                    left_hold <= '0';
                end if;
            end if;
        end if;
    end process;


CS_rot_enc_wr <= '1' when ((ADDR = X"0030") and CS = '1' and RNW = '0') else '0' ;


DIN (0) <= Button_S_int;
DIN (1) <= right_hold;
DIN (2) <= left_hold;
DIN (3) <= rot_center;
DIN (4 to 31) <= (others => '0') ; -- Not used


lcd_rot_cont.cの関連するソフトウェアは下。

    while (1) {
        while (1){
            button_push = XIo_In8(STATUS_ADDR);
            if (button_push == 0x10break;
            else if (button_push == 0x20break;
            else if (button_push == 0x40break;
        }

        // Clear the LCD
        lcd_clear();

        // Print to the LCD
        if (button_push == 0x10){
            lcd_print(1"rot_center ON");
        } else if (button_push == 0x40){ // right -> left
            XIo_Out32(ROT_ENC_ADDR, 0);
            lcd_print(2"left_pulse");
        } else if (button_push == 0x20){ // left -> right
            XIo_Out32(ROT_ENC_ADDR, 0);
            lcd_print(2"right_pulse");
        }
    }


上のソフトウェアで、leftとrightが逆だが、最初は右に回すとleft_pulseと表示されて、左に回すとright_pulseと表示されてしまったので、どうやら逆のようだったので、ソフトウェアの方で反対にした。
下に表示の様子を示す。
SMM_37_101207.jpg
SMM_38_101207.jpg
SMM_39_101207.jpg

これで、ロータリーエンコーダと組み合わせての表示はOKなので、今度はSCCBレジスタ設定回路を修正して、SMMからのコマンドを受け付けるようにするつもりだ。
  1. 2010年12月07日 04:45 |
  2. SMM
  3. | トラックバック:0
  4. | コメント:0

SPACE BATTLESHIP ヤマト(映画)を見てきた

今日も映画を見てきました。SPACE BATTLESHIP ヤマトです。前にアニメも見たので、この実写版も見たかったので、今日見てきました。CGは良かったです。ですが、森雪(黒木メイサ)と古代進(木村拓哉)のラブシーンがうざかった気がしました。全体としては面白かったです。
  1. 2010年12月05日 16:15 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:5

武士の家計簿(映画)を見てきました

昨日は、武士の家計簿という映画を見てきました。
江戸時代物としては、斬り合いがない映画です。御算用者として、加賀藩の経理を預かる(と言っても150人くらいいたようです)経理の武士の話です。結構面白かったですが、最後の盛り上がりには欠けるかな?といった印象でした。
昨日、映画から帰ってから下痢をしてしまったので、体調が悪くなってしまいました。今朝は大丈夫そうなので、今日は、宇宙戦艦ヤマトを見てきたいと思います。
  1. 2010年12月05日 04:34 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:3

The Simple MicroBlaze Microcontroller 7 (50MHzから25MHzへクロックを変更)

今回はSMMリファレンスデザインのクロック周波数を50MHzから25MHzに変更してみる。
今まではWorkの下にリファレンスデザインをコピーしてやっていた。今回は面倒なので、”The Simple MicroBlaze Microcontroller 6(シミュレーション)”までで出来上がっているWorkの下のリファレンスデザインフォルダをWork25Hzにコピーしてやってみることにした。

まずはISEから。50MHzクロックから25MHzの変換するDCMを追加する。Project Navigatorを立ち上げて、右クリックメニューからAdd Source...で、CoreGenのSingle DCM_SPを追加する。出てきたXilinx Clocking Wizard でInput Clock Frequency を50MHz、CLKDVにチェックして、Divide By Value を2にする。
SMM_34_101204.png

lcd_ref.vhdにDCM50_to_25MHzのインスタンスを追加する。CLKDVに接続されたclkを他の回路のクロックとして使用するように変更した。更に他の回路のリセットはreset_lockedに変更した。

-- DCM50_to_25MHz
    Inst_DCM50_to_25MHz: DCM50_to_25MHz PORT MAP(
        CLKIN_IN => Clock,
        RST_IN => Reset,
        CLKDV_OUT => clk,
        CLKIN_IBUFG_OUT => open,
        CLK0_OUT => open,
        LOCKED_OUT => dcm_locked
    );
    reset_locked <= not dcm_locked;


それから、lcd_ctrl.vhdの記述を20ns から40ns に変更した。

constant CLK_PERIOD : integer := 40 ; -- in ns 50MHzから25MHzに変更
-- constant CLK_PERIOD : integer := 20 ; -- in ns


変更は完了したので、これでインプリメントしたら、無事にインプリメントできた。
SMM_35_101204.png

次はSDK。予め、led_reg.c の7行目の”#define CLOCK_PERIOD_NS”を20から40に変更しておいて、SDK12.3を起動した。workspace をWork25Hz/sdkに指定したが、led_ref.cの7行目の”#define CLOCK_PERIOD_NS”は、20のままだった。見ているled_ref.c は以前のファイルになっているようだ。一旦、led_ref.c を削除して、Work25Hz/sdk/led_ref.c をドラック & ドロップでプロジェクトに入れた。
Xilinx ToolsメニューからProgram FPGAを選択して、Program FPGAダイアログが開いたが、Hardware Configuration内のBitstreamもBMM Fileも、以前のWorkフォルダでやっていたときのままのファイルが表示されている(下図参照)。(”The Simple MicroBlaze Microcontroller 4(リファレンスデザイン2)”参照)
ISEはフォルダごとコピーしても、コピーしたフォルダのファイルを使用(相対パス)して、上手くいくが、SDKはプロジェクトを作り直したほうが良いかもしれない?
SMM_36_101204.png

これを、現在のWorkのWork25Hzフォルダの下のファイルに変更した。ELFファイルも指定して、Programボタンをクリックして、FPGAをコンフィグしたら、問題なく文字が表示された。
SMM_23_101127.jpg

これで、動作周波数を25MHzに変更できたので、Spartan-3A Starter Kitによる画像演奏装置に組み込んで、表示を試してみようと思う。
  1. 2010年12月04日 05:58 |
  2. SMM
  3. | トラックバック:0
  4. | コメント:0

ET2010に行ってきました

昨日はET2010に行ってきました。
朝10時から張り切って入場。Xilinxブースへ。PALTEKのHYUGA II ボードの説明を聞きました。なかなか良さそう。そうか勘違いしていたけど、Virtex-6て、3.3V入力できなかったんだっけ?3.3VのICとはレベル変換ICで結んでいるとのことだった。やはり、3.3V出来ないと不便だな。。。DVI IN、DVI OUTはあるが、カメラリンクで直接カメラをつなげあないみたいだ。となりではOmniVision社VGAカメラをレベル変換を通して、パラレルで接続している例があった。
なひたふさんのところでは、AptinaのMT9T031Cの画像を見せてもらったが、綺麗に写っていた。データシートがないので、かなり苦労されたとのことだった。
それから、AXI4バスで構成したMicroBlazeのシステムの動作デモをしていた。ISE12.3からサポートなのに、まともに動くんだ?と感動した。Xilinxは本気かも。。。(これで、EDKがもっと良くなると良いな。。。)
Virtex-6HXTがあって、10.3Gbpsでのデモがあった。アイが開いているのが見えた。これで、ALTERAに並んだか?
Xilinxブースでは、こばさんにも、@DSP_PALTEKさんにもお会いできなかった。残念。。。山猿さんにもお会いしたが、ちょうどなひたふさんのところでお話を聞きたいところだったので、挨拶もそこそこに向かってしまって、失礼してしまった。

11時からセミナーなので、急いでセミナールームへ。Xilinxの28nmのFPGAの紹介。これは一般的な内容だった。もうすでに知っているので、きかなくても良かったかも?これならば、午後のALTERAのFPGAの紹介はパスしよう。
次は、井倉さんのNSLの話。ハードの世界でもUMLで仕様書を書きましょうという話には共感を持った。前々からそう思っていて、勉強しようとしていたのだが、物になっていない。この機会に勉強したい。NSLもやってみたいと思った。いつもながらパワフルで面白いお話、面白かったです。

次は、メンター・グラフィックスの方のFPGAがたまに動かなくなることはありませんか?という物騒なおお話。結局、クロックドメインを渡る信号のクリティカルな部分のお話で、それをメンターのツールで自動的に検出できますよ、というお話でした。Xilinxの非同期FIFOコアを付けて、グレイコードカウンタ出力に制約をかけておけば大丈夫と思うのだが、FF受けでりコンバージェンスの問題はケアしてあったかな?と一瞬ヒヤリとしてしまった。思い返すと、1ビットしか乗り換えてなかったと思うのでセーフ。。。これからは注意したい。その意味でも聞いて良かった。。。

その後は、コンビニで買ってあったおにぎりとパンで昼食。その後、ふらふらと見学しました。ハフトテクノロジの暇村さんにご挨拶をしました。オーバートーンのブースでは井倉さんとお話できました。ブランケットを頂きました。ALTERAも行ってきました。12月6日だったかな?5日だったかな?Quartus II 10.1が出るそうです。Qsysはベータだそうですが、出るそうですよ。SOPC Builderのプロジェクトはまだ読み込めないそうです。だけど、Web Editionでは使えないと言ってましたね。

疲れたので、2階でロイヤルミルクティーで休憩。1時間くらい休憩していたかな?4時くらいになったので、また見学に行きました。
ATOMプロセッサとPCIeで接続されたArria II GXが載っているマザボがあったので、足を止めました。全部C言語で書いて、オフロードしたい部分はプラグマを書いて、Arria II GXに振り分けることができるということでした。面白そう。ハードウェアアクセラレートが出来るのはアプリは限られるのかもしれないけど、面白い。。。ハードにTCP/IP処理をオフロードして、ATOMは他のことをやるとか?さらにFPGAに高性能なプロセッサが入ったら面白いかも?本番はE600のALTERA搭載版が出てからのようですね。
C言語ハードウェアツールはeXCiteを使用していた。ソリトンの方とHLS、FPGAツールの事で盛り上がってしまった。お話できて楽しかったです。

次にアジデントのブースに行って、FPGAのプロービングについてのデモを見せてもらいました。ChipScopeでは、内部のBRAMを使用して波形を保存します。これは、マルチプレクサだけをFPGAに実装して、オシロというかロジアナで見るデモを見せてもらったのですが、プローブをどの順番でつないでもOKでした。それぞれ1パルスずつパルスを出してサーチしているとのことでした。VGAの信号を観測して、どうな表示になるか表示してくれる機能が良かったです。ここでも学生時代にFPGAを使っていたという説明員の方と楽しくお話させて頂きました。

そろそろETフェスタの時間でXilinxブースを見ていると、早乙女さんにお会いした。つくばでカメラのデモをしていただけるとのことだった。

5時なので、Verification Engineerの戯言さんにお会いした。お元気そうだった。飲みに行かれるとのこと、今日は朝からで疲れ気味だし、家も遠いので、飲みに行かないで帰宅しました。今日は暑かったです。着過ぎだったと反省。。。

そうそう、オーバートーンで頂いたブランケット(オレンジ色はレアだそうです)と帰りの横浜、クイーンズタウンのクリスマスツリー。
ET2010_1_101203.jpg

ET2010_2_101203.jpg
  1. 2010年12月03日 05:22 |
  2. その他のFPGAの話題
  3. | トラックバック:0
  4. | コメント:4

The Simple MicroBlaze Microcontroller 6(シミュレーション)

SMMの問題点はシミュレーションができないことだと思う。実機デバックはできるが、シミュレーションは出来ない。EDKを使えばできるのかもしれない?が、それではISEだけでシンプルに実装する目的と合わない。
という訳で、SMMの周辺回路をシミュレーションする簡単なSMMのバスモデルを作ってみた。言語はサンプルがVHDLだったので、VHDLで作った。ISE12.3を使用している。
SMM_noUART_sim_pack.vhdがSMMのWriteサイクルとReadサイクルを行う。と言っても、コードを見てもらえば、すぐわかるようにとても簡単だ。WriteはWR_ADDRにアドレス、WR_DATAにデータ、WR_BEにバイト・イネーブルをセットして、procedureをコールすれば、SMMのWriteサイクルが起動する。Readサイクルは、RD_ADDRにアドレス、RD_BEにバイト・イネーブルをセットすれば、RD_DATAにReadしたデータが出力される。下に、SMM_noUART_sim_pack.vhdを示す。ほとんど”procedureを使うときの注意点”のコードと同じ。

-- SMM_noUART用パッケージ

library ieee;
use ieee.std_logic_1164.all;

package SMM_noUART_sim_pack is
    procedure SMM_WR_CYCLE(
        WR_ADDR : in std_logic_vector; -- 書き込みアドレスをセットする
        WR_DATA : in std_logic_vector; -- 書きこむデータをセットする
        WR_BE : in std_logic_vector; -- 書きこむBEをセットする
        
        signal clk : in std_logic;
        signal rnw : out std_logic;
        signal cs : out std_logic;
        signal addr : out std_logic_vector;
        signal dout : out std_logic_vector;
        signal be : out std_logic_vector
    );
    
    procedure SMM_RD_CYCLE(
        RD_ADDR : in std_logic_vector; -- 読み出しアドレスをセットする
        RD_BE : in std_logic_vector; -- 読み出し時のBEをセットする
        signal RD_DATA : out std_logic_vector; -- 読み出しデータ
        
        signal clk : in std_logic;
        signal rnw : out std_logic;
        signal cs : out std_logic;
        signal addr : out std_logic_vector;
        din : in std_logic_vector;
        signal be : out std_logic_vector
    );
end SMM_noUART_sim_pack;

package body SMM_noUART_sim_pack is
    procedure SMM_WR_CYCLE(
        WR_ADDR : in std_logic_vector; -- 書き込みアドレスをセットする
        WR_DATA : in std_logic_vector; -- 書きこむデータをセットする
        WR_BE : in std_logic_vector; -- 書きこむBEをセットする
        
        signal clk : in std_logic;
        signal rnw : out std_logic;
        signal cs : out std_logic;
        signal addr : out std_logic_vector;
        signal dout : out std_logic_vector;
        signal be : out std_logic_vector
    ) is
    begin
        wait until clk'event and clk='1'; -- clkの立ち上がりまでwait
        wait for 1 ns; -- 遅延を挟んで
        rnw <= '0'; -- Write
        cs <= '1'; -- enable
        addr <= WR_ADDR;
        dout <= WR_DATA;
        be <= WR_BE;
        
        wait until clk'event and clk='1'; -- clkの立ち上がりまでwait
        wait for 1 ns; -- 遅延を挟んで
        cs <= '0';
    end SMM_WR_CYCLE;
    
    procedure SMM_RD_CYCLE(
        RD_ADDR : in std_logic_vector; -- 読み出しアドレスをセットする
        RD_BE : in std_logic_vector; -- 読み出し時のBEをセットする
        signal RD_DATA : out std_logic_vector; -- 読み出しデータ
        
        signal clk : in std_logic;
        signal rnw : out std_logic;
        signal cs : out std_logic;
        signal addr : out std_logic_vector;
        din : in std_logic_vector;
        signal be : out std_logic_vector
    ) is
    begin
        wait until clk'event and clk='1'; -- clkの立ち上がりまでwait
        wait for 1 ns; -- 遅延を挟んで
        rnw <= '1'; -- Read
        cs <= '1'; -- enable
        addr <= RD_ADDR;
        be <= RD_BE;
        
        wait until clk'event and clk='1'; -- clkの立ち上がりまでwait
        RD_DATA <= din;
        wait for 1 ns; -- 遅延を挟んで
        cs <= '0';
    end SMM_RD_CYCLE;
end SMM_noUART_sim_pack;


次にSMMのシミュレーション・モデルを下に示す。process beginの下のwait for 100 ns;の下に試してみたいスティミュラスを記述する。今回は、タイマーに16をセットして、割り込みがかかるのを待ってから、LCDの命令レジスタにX"34"を書きこむ。次に、South Pushbuttonスイッチの状態をReadする。

-- SMMのシミュレーションモデル
-- IO、Interruptのモデル、シリアル無し

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

library work;
use work.SMM_noUART_sim_pack.all;

entity smm is
    port (
      CLK : in std_logic;
      RESET : in std_logic;
      DIN : in std_logic_vector(0 to 31);
      DOUT : out std_logic_vector(0 to 31);
      BE : out std_logic_vector(0 to 3);
      RNW : out std_logic;
      ADDR : out std_logic_vector(0 to 15);
      CS : out std_logic;
      INTERRUPT : in std_logic;
      INTERRUPT_ACK : out std_logic
    );
end smm;

architecture sim_model of smm is
constant LCD_ADDR : std_logic_vector :=     X"0000";
constant TIMER_ADDR : std_logic_vector :=     X"0010";
constant BUTTON_ADDR : std_logic_vector :=    X"0020";
signal rd_data : std_logic_vector(0 to 31);
type INTERRUPT_STATE is (IDLE_INTR, WAIT_INTR1, WAIT_INTR2, INTR_ACK, WAIT_INTR_LOW);
signal intr_cs : INTERRUPT_STATE;
signal INTERRUPT_ACK_node : std_logic;
begin
    -- 割り込み用ステートマシン
    process(clk, reset) begin
        if reset='1' then
            intr_cs <= IDLE_INTR;
            INTERRUPT_ACK_node <= '0';
        elsif clk'event and clk='1' then
            case intr_cs is
                when IDLE_INTR =>
                    if INTERRUPT='1' then -- 割り込み
                        intr_cs <= WAIT_INTR1;
                    end if;
                when WAIT_INTR1 =>
                    intr_cs <= WAIT_INTR2;
                when WAIT_INTR2 =>
                    intr_cs <= INTR_ACK;
                    INTERRUPT_ACK_node <= '1';
                when INTR_ACK =>
                    intr_cs <= WAIT_INTR_LOW;
                    INTERRUPT_ACK_node <= '0';
                when WAIT_INTR_LOW =>
                    if INTERRUPT='0' then
                        intr_cs <= IDLE_INTR;
                    end if;
            end case;
        end if;
    end process;
    INTERRUPT_ACK <= INTERRUPT_ACK_node after 1 ns;
    
    process begin
        DOUT <= (others => '0');
        BE <= (others => '0');
        ADDR <= (others => '0');
        CS <= '0';
        
        wait for 100 ns;
        
        -- これから下のwaitまでの間にスティミュラスを書く
        
        SMM_WR_CYCLE(TIMER_ADDR, X"00000010", "1111", clk, rnw, cs, addr, dout, be); -- Timerへ書き込み、16クロックカウント
        
        wait until INTERRUPT_ACK_node'event and INTERRUPT_ACK_node='1'; -- INTERRUPT_ACK_node の立ち上がりまでwait
        wait for 1 ns;
        
        SMM_WR_CYCLE(LCD_ADDR, X"12340000", "1111", clk, rnw, cs, addr, dout, be); -- LCDへ書き込み
        
        -- ボタンの状況をrd_dataに読み出し
        SMM_RD_CYCLE(BUTTON_ADDR, "1111", rd_data, clk, rnw, cs, addr, din, be);
        
        wait;
    end process;
end sim_model;


次にテストベンチだが、これはSouth PushbuttonスイッチのButton_Sを1にして、ひたすらwaitするだけだ。

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
 
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;
 
ENTITY lcd_ref_tb IS
END lcd_ref_tb;
 
ARCHITECTURE behavior OF lcd_ref_tb IS 
 
    -- Component Declaration for the Unit Under Test (UUT)
 
    COMPONENT lcd_ref
    PORT(
         Clock : IN  std_logic;
         Reset : IN  std_logic;
         Button_S : IN  std_logic;
         LCD_DB : OUT  std_logic_vector(7 downto 0);
         LCD_RS : OUT  std_logic;
         LCD_RW : OUT  std_logic;
         LCD_E : OUT  std_logic
        );
    END COMPONENT;
    

   --Inputs
   signal Clock : std_logic := '0';
   signal Reset : std_logic := '1';
   signal Button_S : std_logic := '0';

     --Outputs
   signal LCD_DB : std_logic_vector(7 downto 0);
   signal LCD_RS : std_logic;
   signal LCD_RW : std_logic;
   signal LCD_E : std_logic;

   -- Clock period definitions
   constant Clock_period : time := 20 ns;
 
BEGIN
 
    -- Instantiate the Unit Under Test (UUT)
   uut: lcd_ref PORT MAP (
          Clock => Clock,
          Reset => Reset,
          Button_S => Button_S,
          LCD_DB => LCD_DB,
          LCD_RS => LCD_RS,
          LCD_RW => LCD_RW,
          LCD_E => LCD_E
        );

   -- Clock process definitions
   Clock_process :process
   begin
        Clock <= '0';
        wait for Clock_period/2;
        Clock <= '1';
        wait for Clock_period/2;
   end process;
 

   -- Stimulus process
   stim_proc: process
   begin        
    reset <= '0';
    Button_S <= '0';
    -- hold reset state for 100 ns.
      wait for 100 ns;    
        Button_S <= '1';
        reset <= '0';
      wait for Clock_period*100;

      -- insert stimulus here 

      wait;
   end process;

END;


これをISEにシミュレーション専用でプロジェクトに追加すると、ImplementationとSimulationでSMMが切り替わってとても具合が良い。
SMM_31_101202.png
SMM_32_101202.png

これでISimでシミュレーションをした結果を下に示す。
SMM_33_101202.png

最初にcsが1になって0に戻ったところで、タイマーに16をセットして、その間waitして、interrupt_ackが来たら、wait状態から抜けだして、次のcs=1でLCDの命令レジスタにX"34"を書きこむ。その結果として、lcd_dbが34になって、lcd_eが260nsecの間、1になる。その次のcs=1でbutton_sの内容をrd_dataの最上位ビットに読み込む。

これで、SMM周辺回路のシミュレーションでのデバックは出来る状況になったと思う。
  1. 2010年12月02日 04:47 |
  2. SMM
  3. | トラックバック:0
  4. | コメント:0

procedureを使うときの注意点

SMMのモデルをVHDLで作っているが、ここ数日間、SMMからWriteするprocedureとSMMからReadするprocedureを作っていた。そんなに日にちがかかるものでもないのだが、エラーが解消できなくて困ってしまった。次にまた同じ問題に悩まないようにブログに書いておく。

さて、procedureは下のようにpackageに宣言してあった。

package SMM_noUART_sim_pack is
    procedure SMM_WR_CYCLE(
        WR_ADDR : in std_logic_vector; -- 書き込みアドレスをセットする
        WR_DATA : in std_logic_vector; -- 書きこむデータをセットする
        WR_BE : in std_logic_vector; -- 書きこむBEをセットする
        
        clk : in std_logic;
        signal rnw : out std_logic;
        signal cs : out std_logic;
        signal addr : out std_logic_vector;
        signal dout : out std_logic_vector;
        signal be : out std_logic_vector
    );
    
    procedure SMM_RD_CYCLE(
        RD_ADDR : in std_logic_vector; -- 読み出しアドレスをセットする
        RD_BE : in std_logic_vector; -- 読み出し時のBEをセットする
        signal RD_DATA : out std_logic_vector; -- 読み出しデータ
        
        clk : in std_logic;
        signal rnw : out std_logic;
        signal cs : out std_logic;
        signal addr : out std_logic_vector;
        din : in std_logic_vector;
        signal be : out std_logic_vector
    );
end SMM_noUART_sim_pack;


いつも、入力はsignal宣言を書かずに、出力だけsignal宣言を書いてある。これは、”HDL設計入門 VHDL階層構造とサブプログラム”によると、すべての信号をsignal宣言すると並列プロシージャとなって、入力信号が変化すると自動的に出力値が変化するそうだ。これは結局、入力信号をすべてセンシティビティ・リストに入れたprocess文と同じと考えることができると思う。
私が使うとしているのは、順次プロシージャなのだが、out信号はsignal宣言をしている。今回も入力のclkはsignal宣言をしていなかった。
下にpackage body を示す。ここでは、wait untilでclkの立ち上がりを待つ記述を使用している。

package body SMM_noUART_sim_pack is
    procedure SMM_WR_CYCLE(
        WR_ADDR : in std_logic_vector; -- 書き込みアドレスをセットする
        WR_DATA : in std_logic_vector; -- 書きこむデータをセットする
        WR_BE : in std_logic_vector; -- 書きこむBEをセットする
        
        clk : in std_logic;
        signal rnw : out std_logic;
        signal cs : out std_logic;
        signal addr : out std_logic_vector;
        signal dout : out std_logic_vector;
        signal be : out std_logic_vector
    ) is
    begin
        wait until clk'event and clk='1'; -- clkの立ち上がりまでwait
        wait for 1 ns; -- 遅延を挟んで
        rnw <= '0'; -- Write
        cs <= '1'; -- enable
        addr <= WR_ADDR;
        dout <= WR_DATA;
        be <= WR_BE;
        
        wait until clk'event and clk='1'; -- clkの立ち上がりまでwait
        wait for 1 ns; -- 遅延を挟んで
        cs <= '0';
    end SMM_WR_CYCLE;
    
    procedure SMM_RD_CYCLE(
        RD_ADDR : in std_logic_vector; -- 読み出しアドレスをセットする
        RD_BE : in std_logic_vector; -- 読み出し時のBEをセットする
        signal RD_DATA : out std_logic_vector; -- 読み出しデータ
        
        clk : in std_logic;
        signal rnw : out std_logic;
        signal cs : out std_logic;
        signal addr : out std_logic_vector;
        din : in std_logic_vector;
        signal be : out std_logic_vector
    ) is
    begin
        wait until clk'event and clk='1'; -- clkの立ち上がりまでwait
        wait for 1 ns; -- 遅延を挟んで
        rnw <= '1'; -- Read
        cs <= '1'; -- enable
        addr <= RD_ADDR;
        be <= RD_BE;
        
        wait until clk'event and clk='1'; -- clkの立ち上がりまでwait
        RD_DATA <= din;
        wait for 1 ns; -- 遅延を挟んで
        cs <= '0';
    end SMM_RD_CYCLE;
end SMM_noUART_sim_pack;


これでISimでコンパイルすると、下のようにエラーが出てしまう。

ERROR:HDLCompiler:989 - "H:/HDL/FndtnISEWork/Simple_MicroBlaze_xapp1141/SMM_Ref/S3A_LCD_Ref/Work/ise/../src/Simulation/SMM_noUART_sim_pack.vhd" Line 48: Attribute event requires a static signal prefix
ERROR:HDLCompiler:989 - "H:/HDL/FndtnISEWork/Simple_MicroBlaze_xapp1141/SMM_Ref/S3A_LCD_Ref/Work/ise/../src/Simulation/SMM_noUART_sim_pack.vhd" Line 56: Attribute event requires a static signal prefix
ERROR:HDLCompiler:989 - "H:/HDL/FndtnISEWork/Simple_MicroBlaze_xapp1141/SMM_Ref/S3A_LCD_Ref/Work/ise/../src/Simulation/SMM_noUART_sim_pack.vhd" Line 74: Attribute event requires a static signal prefix
ERROR:HDLCompiler:989 - "H:/HDL/FndtnISEWork/Simple_MicroBlaze_xapp1141/SMM_Ref/S3A_LCD_Ref/Work/ise/../src/Simulation/SMM_noUART_sim_pack.vhd" Line 81: Attribute event requires a static signal prefix
ERROR:HDLCompiler:854 - "H:/HDL/FndtnISEWork/Simple_MicroBlaze_xapp1141/SMM_Ref/S3A_LCD_Ref/Work/ise/../src/Simulation/SMM_noUART_sim_pack.vhd" Line 34: Unit ignored due to previous errors.


なんだろう?と思って悩んでいたが、ModelSimでコンパイルしてみて、eventが”wait until clk'event and clk='1';”の所のeventだということにやっと気がついた。
clk : in std_logic;

signal clk : in std_logic;
にして、やっとエラーが消えた。

ブログに書いたprocedureを調べてみたら、”VHDLでOVLアサーションを使用する3(VHDLからVerilog OVLを使用する)”で、” wait until clk'event and clk='1';”を使ったprocedureを使っていて、clkの宣言もちゃんと”signal clk : in std_logic;”としてあった。進歩がない。。。退歩している。。。頭に刻みつけようと思う。

  1. 2010年12月01日 05:44 |
  2. VHDLの書き方
  3. | トラックバック:0
  4. | コメント:0