30.LEDをチカチカさせてみよう(Fablic使用)2015/9/22↓30-1. はじめにFablic(FPGA部)を使用してLEDをチカチカさせてみましょう。ボードは A2F-EVAL-KIT を使用します。 Micon(ARM部)を使用してのLEDチカチカは別章で書きますね。 30-2. 初期設定早速LiberoSocを起動してみましょう。ディスクトップのLibero SoC v11.5をダブルクリックします。Liberoが立ち上がります。最小化されて立ち上がる事があるのでその時はタスクバーのLiberoをクリックして表示させましょう。 ![]() 次にツールバーのProject->New Projectを選びます。 Project Details が開きます。 Project Name: に led_chika_fpga Project Location: に C:/Users/shibatchii/Smartfusion/led_chika_fpga <- ここはご自分のディレクトリに合わせてくださいね。 Description: に LED chika FPGA <- ここは説明なのでわかりやすい内容を書いておきましょう。 Preferred HDL Type: Verilog を選びます。 Enable Block Creation は チェックを付けないでおきます。 Next> をクリックします。 ![]() Device Selection が開きます。 今回はA2F-EVAL-KITボードを使用するのでそのボードに乗っているFPGAを選択します。 Family: SmartFusion Speed: STD Die: A2F200M3F Core voltage: 1.5 Package: 484FBGA Range:COM A2F200M3F-FG484が表示されているはずですので選択します。 Next> をクリックします。 ![]() Device Setting が開きます。 Default I/O Technology: LVTTL あとで変えられるのでとりあえずLVTTLで。 Unused MSS I/O Resister Pull: None 未使用のピンはPullUp,PullDownが選べますが何もしないとします。 Reserve Pins for Probes は チェックが付いたまま変えられないようになっています。 Next> をクリックします。 ![]() Design Template が開きます。 Design Templates and Creators は Create a Microcontroller(MSS) based design を選択します。 あれー、マイコン部使わないんじゃなかったの? と思われるかもしれませんが MSS の PLLとリセット コントローラのみ使います。マイコンとしての機能は今回使いません。 SmartFusion Microcontroller Subsystem(MSS) 2.5.1 06 が選択されています。 Next> をクリックします。 ![]() Add HDL Source Files が開きます。 後で LチカのRTLを追加するので、ここではなにもせずに Next> をクリックします。 ![]() Add Constraints が開きます。 これも、後で追加するので、ここではなにもせずに Finish> をクリックします。 ![]() 30-3. MSS設定少し待つと以下のようにMSSが表示されます。 今回のLEDチカチカには不必要なものも選択されているので非選択にしましょう。 (UARTとかSPIとかI2Cとか...は使いません。 表示されている led_chika_fpga_MSS_0 をダブルクリックしてください。 ![]() ed_chika_fpga_MSS_0 の中身が表示されました。 見やすいようにウィンドウを調整して大きく見えるようにしましょう。 で、これがMSS、つまりCoretexM3マイコンとあらかじめ備え付けのIP、つまりいろいろな機能です。 小さくてわかりずらいのですが各ブロックの右下にチェックボックスがついているのがあります。 このチェックボックスでその機能を使う(ONにする)か使わない(OFFにする)か決まります。 また、スパナマークはそのブロックがいろいろ設定を変えられることを示しています。 今回はClockとReset以外は使わないのでチェックを全部外します。 ![]() チェックをはずすとこんな感じです。MSS_RESET_Nだけ端子があります。 これからクロックとリセットの設定をしていきます。 まずクロックの設定をします。 Clock Managementのブロックをダブルクリックしてください。 ![]() Microcontroller Subsystem Clock(s) Configurator が開きます。 赤線で囲んだところを設定します。 今回は1MHzをRTLで ・クロック元はMain Crystal Oscilator を選択 ・PLLからの出力を選択 ・出力周波数は1.000MHzに設定 ・FAB_CLK(GLA1)にチェック 設定し終わったら OKをクリックします。 ![]() 次にリセットの設定をします。 MSSからFPGA部(Fabric)に対してリセット制御します。 Reset Management ブロックをダブルクリックします。 Fabric Resets で Enable MSS To Fabric Reset にチェックをいれます。 OKをクリックします。 ![]() 設定が終わった MSS設定画面です。 ・MAINXIN ・MSS_RSET_N ・FAB_CLK ・M2F_RESET_N の端子があるはずです。 ここでいったんセーブします。 Ctrl+S もしくは セーブアイコン、もしくはFile->Save led_chika_fpga_MSS をします。 ![]() 次に Generate Component します。【重要】 これを忘れると次のステップでMSSが現れず回路を構築できません。 MSS画面の左ウエイにある黄色いドラム缶と歯車のようなアイコンをクリック、もしくは SmartDesign->Generate Component をします。 少し時間がかかります。(1分位) 完了すると左ペーンのCoonfigure MSSに緑のチェックが付きます。 ![]() led_chika_fpgaのタグに戻ります。 するとled_chika_fpga_MSS_0の右上に黄色い三角のびっくりマークがついています。 ようするに中身が変わってるよ!っていうことを示しています。 そこで、右クリックして Update Instance(s) Latest Component...を選びます。 ![]() そうすると下位のコンパイルされたMSSに合わせた端子になります。 ![]() -------- 30-4. LEDチカ設計さて、MSSの方の準備はできたのでここでLEDチカの回路を設計しましょう。 仕様としては ・1MHzの信号を分周して1Hzの信号を生成する。 つまりLEDとしては0.5秒点灯、0.5秒消灯を繰り返す。 です。 1MHzは1,000,000Hzですから、単純に1/1,000,000すれば良いのですが、 まず1/1000して1kHzの1パルス@1MHzを作り、さらに1/500して0.5Hzの1パルス@1MHzを作り、 最後にそれを1/2してデューティ50%の1Hzの信号を作ります。 タイミング図を描いてみると以下のようになります。 ![]() これを元に回路を考えます。 まず上記のタイミング図を基におおまかな信号処理を設計します。 緑のところはDFFがある場所です。 ![]() 次にそれぞれのブロック詳細を設計します。 ■ 1000分周カウンタ(r_cnt1[9:0]) ![]() ■ 1000カウント判定(w_cntpls1) ![]() ■ 500分周カウンタ(r_nct2[8:0]) ![]() ■ 500カウント判定(w_cntpls2) ![]() ■ 2分周(r_led)) ![]() はい、ということでLED回路設計できましたね。(オィ!) 30-5. LEDチカHDL作成さて、設計したLEDチカ回路のRTLを作成してみましょう。 led_hdl.vという名前でRTL作成してみます。。 Design Flowから CreateHDLを選びます。 HDL Type はVerilog を選択します。 Nameにled_hdlを入れます。 Initialize file with Template にチェックを入れます。 OKをクリックします。 ![]() HDLのテンプレートを使った画面が開いたと思います。 せっかくなので内容を見てみましょう。 // Company: <Name> 会社名ですね。個人の場合は名前でもニックネームでもプロジェクト名みたいな感じでもよいでしょう。 // File: led_hdl.v お、ちゃんとファイル名が入ってますね。 // File history: // <Revision number>: <Date>: <Comments> // <Revision number>: <Date>: <Comments> // <Revision number>: <Date>: <Comments> ファイルの変更履歴です。履歴番号、日付、コメント 面倒くさがらずに書きましょうね。 1.00 : 2015/11/23 : New とかでよいでしょう。 // // Description: // // <Description here> 説明ですね。何する回路か書いておきましょう。注意書きとかも。しばらくすると、「あれ、なんの回路だったっけ?」なんてことが起こらないように。 // // Targeted device: <Family::SmartFusion> <Die::A2F200M3F> <Package::484 FBGA> // Author: <Name> 作成者の名前ですね // ここから下がVerilogの本体記述です。 /////////////////////////////////////////////////////////////////////////////////////////////////// `timescale <time_units> / <precision> タイムスケール、どういう時間単位で、どういう刻みでというのを示します。 1ns/1ns とかですね。 module led_hdl( <port1>, <port2>, <port3>, <port4> ); モジュール名、ちゃんとled_hdlと入ってますね。あとポート名、どんな名前で入出力するか書きます。 input port1, port2; output port3; inout port4; ポートがどういう性質を持っているか書きます。とはいっても大体はinput,ouput, とバス幅位のものです。 <statements> ここからずらずらとVerilogで回路を記述していきます。 endmodule 最後は endmodule で終わりです。 ![]() で、実際にRTLを書くとこのような感じになります。 しゃらんら〜〜〜〜〜♪♪♪ はい、RTLできました。(オィ) /////////////////////////////////////////////////////////////////////////////////////////////////// // Company: Shibatchii Denki // // File: led_hdl.v // File history: // 1.00: 2015/08/25: New // // Description: // // LED ON/OFF 1 Sec // // Targeted device: <Family::SmartFusion> <Die::A2F200M3F> <Package::484 FBGA> // Author: @Shibatchii // /////////////////////////////////////////////////////////////////////////////////////////////////// `timescale 1ns / 1ns module led_hdl( xrst, clk, led ); input xrst; // Reset input clk; // Clock output led; // LED out reg [9:0] r_cnt1; // 1MHz->1kHz Counter reg [8:0] r_cnt2; // 1kHz->0.5Hz Counter reg r_led; // LED out register wire w_cntpls1; // 1kHz Count pulse wire w_cntpls2; // 0.5Hz Count pulse // Output assign led = r_led; // 1MHz->1kHz Counter always @(posedge clk or negedge xrst)begin if(xrst==1'b0)begin r_cnt1[9:0] <= 10'd1; end else begin // Initial load if(w_cntpls1 == 1'b1)begin r_cnt1[9:0] <= 10'd1; end // Count up else begin r_cnt1[9:0] <= r_cnt1[9:0] + 10'd1; end end end // Counter is 1000 assign w_cntpls1 = (r_cnt1[9:0] >= 10'd1000) ? 1'b1 : 1'b0; // 1kHz-> 0.5Hz Counter always @(posedge clk or negedge xrst)begin if(xrst==1'b0)begin r_cnt2[8:0] <= 9'd1; end else begin // Initial load if(w_cntpls2 == 1'b1)begin r_cnt2[8:0] <= 9'd1; end // Count up else if(w_cntpls1 == 1'b1) begin r_cnt2[8:0] <= r_cnt2[8:0] + 9'd1; end else begin r_cnt2[8:0] <= r_cnt2[8:0]; end end end // Counter is 500 assign w_cntpls2 = ((r_cnt2[8:0] >= 9'd500)&&(w_cntpls1 == 1'b1)) ? 1'b1 : 1'b0; // Toggle always @(posedge clk or negedge xrst)begin if(xrst==1'b0)begin r_led <= 1'd0; end else begin // toggle if(w_cntpls2 == 1'b1)begin r_led <= ~r_led; end // Hold else begin r_led <= r_led; end end end endmodule 最初の1MHz-1kHzカウンタと Counter is 1000 の箇所で1MHzを1000分周して1kHz@1MHzのパルス(w_cntpls1)を生成しています。 次の1kHz-0.5HzカウンタとCounter is 500の箇所でさらに分周して0.5Hz@1MHzのパルス(w_cntpls2)を生成しています。 で、最後にw_cntpls2ごとにトグルする信号を生成し、0.5秒点灯、0.5秒消灯としています。 入力し終えたら、HDLのチェックをしておきましょう。 画面のチェックをクリックすると問題なければChecking of "led_hdl.v" is successful と出ます。 もし問題があるとエラー表示されますので、表示された行をみて修正しましょう。 エラーがなくなったらOKです。 ![]() 30-6. HDL組み込み作成したRTLをled_chka_fpgaに組み込みます。 まず、左側のペーンをDesign Hierarchy に切り替えます。 そうするとled_hdl(led_hdl.v)というのができているはずです。 それをドラッグしてMSSの画面にドロップします。 そうするとインスタンスが自動生成されます。 インスタンスはつかんで動かすことができます。 ダブルクリックすると中のHDLを見ることができます。 ![]() 配線と出力ポート作成をします。 Add Port アイコンをクリックします。NameにLEDをいれDescriptionにOutputとします。OKを押すと画面に配置されます。 Connection Modeアイコンをクリックします。FAB_CLK端子のところでクリックしそのままclkまでドラッグします。表示が丸でかこんだ+マークになると接続できます。 同様にM2F_RESET_Nからxreset、ledからLEDに接続します。 完了したらセーブします。 Generateも忘れずおこなっておきます。 左側のDesign Hierarchyでled_chika_fpgaの下にled_hdlが移動したことがわかります。 30-7. LEDチカHDL検証ちゃんと動作するかどうかシミュレーションしてみましょう。 まずは、テストベンチを作成します。こういう信号を作成したHDLに入力する、出力されてくるよ信号をモニタするといったものです。 今回の場合は入力するのはリセット信号と、クロック信号。モニタするのはLED用の出力信号です。 画面のDesignFlowよりCreate HDL Testbenchを選びます HDL TypeはVerilog、Nameはt_led_chika_fpga、Clock Period(ns)は50とします。20MHz==50nsであるため。OKをクリックします。 ![]() テンプレートからのt_led_hdlが生成されます。 内容はさきほどのHDLのテンプレートとよく似ています。 ここで検証の記述を書きます。 しゃらんら〜〜〜〜〜♪♪♪ はい、テストベンチできました。(オィ) /////////////////////////////////////////////////////////////////////////////////////////////////// // Company: Shibatchii Denki // // File: t_led_chika_fpga.v // File history: // 1.00: 2015/11/23: New // // Description: // // Lec Chika Testbench // // Targeted device: Family:SmartFusion Die:A2F200M3F Package:484 FBGA // Author: Shibatchii // /////////////////////////////////////////////////////////////////////////////////////////////////// `timescale 1ns/1ns module t_led_chika_fpga; parameter SYSCLK_PERIOD = 50;// 20MHZ reg SYSCLK; reg NSYSRESET; initial begin SYSCLK = 1'b0; NSYSRESET = 1'b0; end ////////////////////////////////////////////////////////////////////// // Reset Pulse ////////////////////////////////////////////////////////////////////// integer i,j,k,l; initial begin #(SYSCLK_PERIOD * 10 ) NSYSRESET = 1'b1; end ////////////////////////////////////////////////////////////////////// // Clock Driver ////////////////////////////////////////////////////////////////////// always @(SYSCLK) #(SYSCLK_PERIOD / 2.0) SYSCLK <= !SYSCLK; ////////////////////////////////////////////////////////////////////// // Instantiate Unit Under Test: led_chika_fpga ////////////////////////////////////////////////////////////////////// led_chika_fpga led_chika_fpga_0 ( // Inputs .MSS_RESET_N(NSYSRESET), .MAINXIN(SYSCLK), // Outputs .LED(w_led) ); initial begin repeat(10) begin @(posedge SYSCLK); end for(l=0;l<4;l=l+1)begin // 2 times for(k=0;k<500;k=k+1)begin // 1kHz->0.5Hz for(j=0;j<1000;j=j+1)begin // 1MHz->1kHz for(i=0;i<20;i=i+1)begin // 20MHz->1MHz PLL @(posedge SYSCLK); end end end end repeat(1000) begin @(posedge SYSCLK); end $finish; end endmodule テストベンチを少しみておきましょう。 最初はコメントですね。 moduleからがテストベンチ本体です。 SYSCLKとNSYSRESETを宣言して初期化しています。 動作開始して10clkでリセット解除しています。 Clock Dividerのところでクロック生成しています。CLOCK_PERIODの1/2周期ごとに反転させています。 led_chika_fpga led_chika_fpga_0 のところで下位のHDLを呼び出し(インスタンス化)するとともに、信号接続しています。 initial begin のところでひたすら時間待ちしています。LEDが2回点滅する時間だけまたせています。 $finish;でシミュレーション終了です。 RTLの時と同じようにCheck HDL Fileでチェックしておきましょう。br> それでは早速シミュレーションみましょう。 Dataflowから Open Interractivery を選択します。 ![]() そうするとModelSimというシミュレータが立ち上がります。 左のsim-defaultに階層が表示されます。いろいろありますが、t_led_chika_fpgaとled_chika_fpgaがありますね。 真ん中のObjectsはsim-defaultで選択されている階層の信号名が示されています。 右のWave-Defaultには波形が表示されます。 あれ何にも動いてないじゃんって思われるかもしれませんが、表示されている時間が短いので全体が見えてないのです。 ![]() まず、Wave-Defaultをクリックします。そして黒い虫眼鏡(Zoom Full)をクリックします。 すると、20clkほど表示されます。おお、なんだか動いているような雰囲気です。 テストベンチでは2回LEDがH,Lしてるはずのに少なくない?と思われるかもしれませんが、実行スクリプトで1000nsまでと指定してあるからなんですね。 後でちゃんと最後まで実行させてみます。 その前に、RTL内の信号もモニタできるようにしておきましょう。sim-Defaultでled_chika_fpgaを選択(1)するとObjectのところに信号が表示されます(2)。 それを選択してWave-Defaultにドラッグドロップします(3)。 信号名が見えるようにスライダーで調整しておきましょう。 ![]() さて、いよいよ全時間実行してみましょう。 まずRestartをクリックします。ダイアログがでるので全部チェックが入っていることを確認してOKをクリックします。 その後、Run -All を選択すると実行が始まります。 ![]() シミュレーションが完了するまでかなり時間がかかるので、遊びに行くなり、晩御飯を食べるなり、寝るなりして待ちましょう。 私のところでは大体1時間かかりました。 ツール付属のFree版なのでしょうがないですね。製品版なら数秒か数十秒位で終わるはずです。 終了すると終了していいかダイアログが出ます。ここではいいえを選択します。はいを選択するとそのまま終了してしまいます(泣)。 ![]() そうするとテストベンチが表示され$finishのところを示しています。 波形はどこいった?と思われるかもしれませんが、安心してください、残ってますよ。ということで右上のXをクリックして消しましょう。 ![]() 波形が表示されたはずです。ただ時間間隔が小さくでどう動いているかわからないので、さきほどと同じように Zoom-Fullをクリックします。 再描画にはちょっと時間がかかります。 波形が表示されw_ledがパタパタしていることがわかりますね。 LED_net_1の立ち上がりのところをクリックするとカーソル(黄色の縦線)が表示されます。 1周期の時間間隔を測定するためにもう1つカーソルを追加します。 Add - To Wave Cursor を選択するとCursorがもう1こ増えます。 ![]() 増えたCursorをつかんで次の立ち上がりのところに持っていきます。 下の方に間隔が表示されています。 ちょうど1000000000nsとなっています。1秒ですね。設計通りです。 ![]() これでシミュレーションを終了します。 File Quit を選択すると、Are you sure you quit? と表示されるので はい を選択します。 ![]() 30-8. LEDチカHDL合成、フィッテング回路の確認もできたことですしいよいよ論理合成、とフィッティングを行います。Generate Programing Data をまずはクリックしてみましょう。 数分で完了するはずです。Pre-Sinthesis SimurateでErrorが出ていますが 今回の回路に関係ないところで出ているようなので無視しても問題ありません。 その他のところにエラーがでていなければまずはOKです。 もしエラーが出ているようならメッセージを見て修正しましょう。 ![]() さっそく、FPGAボードに書き込んで...って、いや、まだです。 LED出力がFPGAのピンを通じてボード上のLEDに接続される経路を確定しなければなりません。 つまりこのLED出力はFPGAのこのピンから出力するよ。っていうことを指定してあげないといけません。 ピン割り当てにはCreate/Edit I/O Attribute をダブルクリックします。 ![]() DesignerとMultiView Navigatorが立ち上がるはずです。 使用するのはMultiView Navigatorの方です。 画面を見るとMSS_RESETNやMAINXINは灰色になっており選択できないようになっています。 これは専用ピンが割り当てられているためです。 で、LEDのピンですが現在適当なピンが割り当てられています。 これをボードのLEDに割り当てるのですが、どこに割り当たっているの?というのはボードの回路図を見る必要があります。 その情報はMicrosemiのSmartFusion Evaluation Kit ページにあるります。 http://www.microsemi.com/document-portal/doc_download/130773-smartfusion-evaluation-kit-user-s-guide へのリンク 上記リンクからA2F_EVAL_KIT_UG.pdfをダウンロードします。 このPDFのP7を見ると8個のLEDが示されています。ここではD1のLEDを点滅させることにします。 D1はLED1_Nという信号名でFPGAに接続されていることがわかります。 LED1_Nを探すとP18にB19ピンに接続されていることがわかります。また、P35の一覧表でもB19ピンであることがわかります。 ![]() ![]() ピンがわかったところで I/O Attribute Editorで割り当てましょう。 LEDのPin Number を B19にします。Lockedにもチェックをいれます。 完了したら Commit and Check をクリックして保存とチェックを行いましょう。 エラーが表示されなれればOKです。File - Exit で閉じます。 ![]() 次にDesignerを見ると Layoutが灰色になっているはずです。 そこでLayoutをクリックします。Layout Optionを聞いてきますが、そのままOKとします。 すると今変更したピン割り当てで再配置してくれます。 ![]() 次に FlashPro Data File をクリックします。 これでFPGAに書き込めるデータが作成できます。 Export Flash Pro file と聞いてくるので led_chika_fpga.fdb として 保存します。 ![]() ファイル作成ができたのでDesignerを閉じます。 File - Exit すると Save changes to led_chika_fpga.adb ? と聞いてくるので はい を選択し終了します。 30-9. LEDチカHDL合成、フィッテング実際にボードに書き込んで本当に動作するか試してみましょう。まずボードをPCとUSBで接続します。 2本あるので両方接続してください。 ![]() Design Flow のProgram Deviceをクリックします。 Running Program Device, Please do not interrupt. と表示されます。 ![]() ボードでは緑のD13が消灯し、燈色のD14が点滅します。 しばらくしてD13が点灯し、D14が消灯すれば完了です。 D1がチカチカしているはずです。 動画を撮ったのでYouTubeのリンクを張っておきます。 https://www.youtube.com/watch?v=_fYn9MGWxdY へのリンク 以上でSmartfusionのFablic(FPGA)部を使ったLEDチカは完了です。 次回はFablicを使わずにマイコン部だけでLEDチカしてみたいと思います。 2015/11/29↑ |
![]() |