2009/01/14(水)[HDL][Quartus II] constant function
[Quartus II][HDL]今日の不思議:constant functionが作れない?
状況
parameter化を行うため,カウンタに必要なビット数を得たいと考えた.同様のVHDL実装は,FPGAの部屋で紹介されていました.どこかで見かけたなぁと思ったら,Verilog2001-LRMの"constant function"の使い方として紹介されていました.
ところが,QuartusII v8.1(SOPC Builderのmodule登録時のAnalysis)にてsynthesisを試みたところ,エラーが出てきました.エラーはVerilog codeの中にコメントで記します.
妄想
function文が,constantを返すと認識していないようですねぇ.\QuartusIIの制限事項にでも記載されているのかしら(未確認).Verilog-2001対応のはずですよね...
とりあえずcounter変数をintegerとして逃げました.regでビット幅を指定すると,余計なレジスタを作らないので安心なのですが.integerならbit幅違いや定数のビット数指定が抜けてもwarningが出ないので見た目が気持ち良いというか何というか….
parameter CLK_DIVIDER = 2 ; localparam CLK_DIVIDER_WIDTH = clogb2(CLK_DIVIDER) ; // Error: Error (10192): // Verilog HDL Defparam Statement error at avalonif_dai.v(49): // value for parameter "CLK_DIVIDER_WIDTH" must be constant expression File: ---- ////////////////////////////////////////////////////////////////////// // Verilog LRM "10.3.5 Use of constant functions" // // define the clogb2 function function integer clogb2; input depth; integer i,result; begin for (i = 0; 2 ** i < depth; i = i + 1) result = i + 1; clogb2 = result; end endfunction
参考(VHDLでのLOG2実装例)
ttp://www.opencores.org/cvsweb.cgi/~checkout~/AVR_Core/VHDL/AVRuCPackage.vhd?rev=1.1.1.4;content-type=text%2Fplain
勝手に持ってきたのでこっそりと(ぇ
-- Functions function LOG2(Number : positive) return natural is variable Temp : positive := 1; begin if Number=1 then return 0; else for i in 1 to integer'high loop Temp := 2*Temp; if Temp>=Number then return i; end if; end loop; end if; end LOG2; -- End of functions
2009/01/06(火)[SOPC] 長船さんのMMC/SPIインタフェース
はじめに
SPIコアのコメントで,長船さんからSDカードアクセスまで動作した実績のIPを開示いただいた.これをNEEKに組み込んでみようというネタ.
動作確認ができたのでクローズ.HDL開示は別記事にて予定...
問題発生
いただいたVHDLコードをとりこんで,SOPC Builderで論理合成をパス.しかし,Nios II IDEで作ったコードをダウンロード実行してもSDカードのIDLEへの遷移が確認できず(デバッガによるトレース).
実績のあるIPであることから,端子割付やタイミング設定が怪しまれる.ModelSimは,WEB editionだとVerilog-HDLとVHDLの混在シミュレーションができない*1.
勉強もかねて,Verilog-HDLへの移植を行うこととした.
やったこと/やってること/やろうとしていること
やったこと~1
- 机上確認
- Verilog移植\OK@6/Jan./2009\長船さんから公開していただいたSPI interface IPを元に移植.FatFSも最近のものへと置換した.\レジスタ初期化漏れをsimulationで検出し,修正済み.\(実使用上は問題ない.合成時にロジックが増えるかもしれないので,ゲート数削減のためにリセット時未初期化にしたのかもしれない.)\OK@7/Jan./2009\tclを手動編集:set_interface_property avalon_slave_0 addressSpan 1024\TOPレベルモジュールのport宣言でin/outを間違っていた.\Timeout検出用のカウンタ(FRC)の実装漏れ….あとで処理しようとして放置していた.ボケとる.
- Simulation確認\たぶんOK@6/Jan./2009\制御レジスタへのアクセス,SCKtxdatレジスタの変化を確認できた.
- ピンアサイン確認\SDまわり
問題なしぽい.@1650訂正\TOP moduleにて,DI/DOを逆に接続していた.下表のようにまとめてみると間違いに気づけるわ….\本日実機を持ってきていないのでここまで.\参考:NEEKの端子一覧(まとめなおして移動するかも?)
SD pin | symbol name | Direction | HSMC name | HSMC pin | FPGA pin name |
---|---|---|---|---|---|
CMD/DI | HC_SD_CMD | FPGA.output | HSMC_D3 | HSMC#44 | FPGA-L6 |
DAT/DO | HC_SD_DAT | FPGA.input | HSMC_D5 | HSMC#48 | FPGA-M3 |
DAT3/CS | HC_SD_DAT3 | FPGA.output | HSMC_D8 | HSMC#53 | FPGA-N8 |
CLK | HC_SD_CLK | FPGA.output | HSMC_TX_p8 | HSMC#101 | FPGA-M2 |
- 実機確認
signal測定\レベル確認(アナログ),SCK確認,SDI確認(SD挿入時).(TxDataは0xFFなので変化しない)タイミング確認(実時間)\\
何か出ているならロジアナで吸い上げてタイミングを確認する.
- SD応答確認
期待通りならSDカードを取り替えたりして確認する.
やったこと~2
ModelSim(WebEdition)にて,タイミング確認.
- DMA機能を使わず,SPI部のみを使った動作確認\→正常に動作した
- DMA機能のステートマシンチェック\→シミュレーションレベルでは正常そう
- DPRAMアクセス\write機能が無かったのでエイヤで実装した.\byte enableを使ってBYTEアクセスを許容し,write時にもDMA転送ができるように見越しても良いだろう.
最終日のオチ
- Verilogへの移植の際に実装漏れ,実装ミスがあった.
- MegaWizardで生成したDualport RAMブロックについても,出力段にレジスタを入れていたため,リードレイテンシ2でのCPU読み出しが成功するときとしないときがあった.\NiosII IDEから8bit/16bit/32bitアクセスを行った際に,連続・ステップ実行・Memory Dumpで読み出せる値が変化したことから明確になった.
※32bit接続のIPであっても,NiosIIのDynamicBUS sizing?により必要な値(BYTE)だけを正しく取得することができた.おそらくarbitorのあたりでうまいことやってるのだろう.
メモ
SPI/MMCインタフェースIPの移植
Avalon-MM I/Fの参考にさせていただきました.Quartus II 8.1の SOPC builderにある,Wizardを使ったりしながら再構築.tclファイルを作らせるために,Wizardを使ったほうが便利かもしれません(慣れればテキストのほうが早いか?).
当初はAvalon-MMの読み出しにレイテンシ2としていたのが不思議であったが,メモリセルのレイテンシであることが理解できた.レジスタリードについては,常にデコードしており,chipselect信号がアサートされればreaddataに正しい値が出力される.
レイテンシ0の場合って,前段のDDがアドレス・制御信号を出した次のクロックで出力をラッチするんですよね...アービタも通るし,配置制約として効いてきそうな気がしますねぇ.
動作としては,SDからリード時に,IP内のDPRAMへ指定ワード数だけデータ転送を行うIPでした.CPUのポーリング動作が要らないので便利そうです.
書き出しはCPU転送になっているようですが,現状読み出ししか考えて無いので問題なし.
拡張してAvalon-ST source portとしてデータクラスタだけ吐き出せると旨いかもしれないですね.ストリーミング再生時,CPUを介さずに音声なり動画なりを再生させることができそう.
まだまだ先の話ですが
モジュールのアドレス空間
offset | symbol | description |
---|---|---|
0 | status | SPIステータス,送受信データ(8bit) |
1 | divide | SPI clockに用いるmodule入力クロックの分周比(FofSCK = 入力周波数/divide/2) |
2 | timer | タイムアウト検出用ダウンカウンタ(module input clockで動作).0で止まる |
3 | reserved0 | (予約/現実装ではstatusが見える) |
4 | dmastatus | DMAステータス |
5~ | reserved[123] | (予約) |
128~ | readbuff[128] | DMA転送バッファ(現状読み出しのみ) |
※offsetは,32bit word指定.CPUからのアドレスは x4して見える.※使用メモリ256Word = 1024Byte = 10bit
ビットフィールド
status(MMC IF status)
bit | description | mmc_spi.hシンボル |
---|---|---|
31-16 | const zero | - |
15 | 割込み許可フラグ | 1:mmc_irq_enable |
14-13 | const zero | - |
12 | MMC I/F FRCゼロフラグ | 1:mmc_zf_bitmask |
11 | MMC-Write Protect | 1:mmc_wp_bitmask |
10 | MMC-Card Detection | 1:mmc_cd_bitmask |
9 | MMC I/F転送フラグ(0書き込みで転送開始要求) | 1:mmc_commexit / 0:mmc_commstart |
8 | MMC Chip Select(Active Low) | 1:mmc_selnegete / 0:mmc_selassert |
7-0 | MMC I/F受信データ | 8bitデータ.読み出し=RxData,書き込み=TxData(txdataのリードバック不可) |
dmastatus
bit | description | mmc_spi.hシンボル |
---|---|---|
31-16 | const zero | - |
15 | DMA function IRQ enable bit(1:enable, 0:disable) | mmc_dmairq_enable |
14 | assert(0->1) when transfer-ends | mmc_dmadone_bitmask |
13 | 1:受信データエラー@SPI | mmc_dmade_bitmask |
12 | 1:受信タイムアウト@SPI | mmc_dmato_bitmask |
11 | const zero | - |
10 | w1:転送開始,r1:転送中/r0:転送終了 | mmc_dmastart |
9 | const zero | - |
8-0 | 転送バイト数 | - |
2008/12/22(月)[QuartusII] WEB editionでJTAGクロックにremoval error
[QuartusII] WEB editionでJTAGクロックにremoval error
前回,[QuartusII] TimeQuestのaltera_reserved_tckのremoval errorということで,長船さんにコメントをいただいた件を検証してみた.
タイトルに答えを書いている気がしないでもないが...(汗;
Subscription Licenseが有効な場合
各種IPもライセンスvalidateされている状態なので,JTAG接続の必要は無い.
結果としては,SRからの回答もあったように,removal timing errorの発生も無い.
むしろ,altera_reserved_tckがclockとしてリストアップされない.Technology MapViewerにて,PostMapping後の該当回路周辺を見てみると,以下のようになっていた.
なんかaltera_internal_jtagのポートが記憶と異なる...
Subscription Licenseが無効な場合(WEB edition)
いわゆるWEB editionでも見てみた.
どうだろうか.赤枠で囲った3つのポートが増えていることがわかるだろう.
- SHIFTUSER
- CLKDRUSER
- UPDATEUSER
timing errorを出していたのはこの余計な信号生成とかが絡んでいるせいと思われる.また,発生する条件も,これら追加された信号のあたりと推定するため,通常動作中には悪影響はなく,JTAG切断時やtime out時にタイミング違反となる可能性があるのかもしれない.
したがって,本件は問題ナシとしてcloseする.
この辺りを見てしまうと,NiosIIライセンスなしでQuartus II/SOPC Builderを使い続けるのは,色々とライセンス問題で泣かされそうな予感がしてくる.
評価に影響がないように... と考えるとあれか,30日の機能評価版を使えということか.WEBで情報が少ない理由はココにあるのかもしれないな...
儂はどう動くべきなんだろうかな.
Nios IIコアを捨てて,テキトウなCPUコアを持ってくるのも一つだろう.SOPC BuilderのGUIは捨てるのが惜しいので,Avalonシステムは継承したいところだな...
とりあえずもう少し何かカタチができるまでは続けよう...
いただいたIPを使ってファイルアクセスを試したいところですが,中間フォロー資料を先に作らせていただきたく.今週中には第一報を出します.*1
2008/12/20(土)[QuartusII] TimeQuestのaltera_reserved_tckのremoval error
altera_reserved_tckのremoval error
Nios IIのCPUコアを使ったときの話.
いつものようにWarningが大量に出てきているので,自動生成ファイルを含めて中身を眺めていた.ふと,cpu.sdcを見るとこのようなコメントが見つかる.
#************************************************************** # Timequest JTAG clock definition # Uncommenting the following lines will define the JTAG # clock in TimeQuest Timing Analyzer #**************************************************************
確かに,clockが1つだけunconstraintになっていた.これのせいですな.
で,これをコメントインするとですね,表題の問題にぶちあたるわけです.
※画像は"新規ウィンドウで開く"を推奨
前提条件
折角会社で(ryServiveRquestで問い合わせて見ていますが,未解決.アドバイスをいただいたのもコミで,とりあえず下記の設定で試しています.
cpu.sdc
以下をコメントインする.
create_clock -period 10MHz {altera_reserved_tck} set_clock_groups -asynchronous -group {altera_reserved_tck}
そして,以下の一行をgenerated clockも制約に追加(SRにより追記OK)
set_clock_groups -asynchronous -group {altera_internal_jtag|tckutap}
setting
Project右クリック→settingを開く.で,hold timingを保障するように頑張ってくれるらしい.
結果
Quartus II WEB editionを使うと,こうなった.家と会社の自前PCと師のPCでも同様.
コレに対して,同じプロジェクトを送付してあるのだけれど,errorはでないというコメントであった.
とりあえず,サブスクリブ版でも試してみようかと思う.試してもらう,が正解か(縛
申し訳ないが,コレの確認ができるまではcloseできない...?
デフォルトでコメントアウトされていたので,無視していたのだけれど,特に問題なく動いてそうなんですよね.JTAG-UARTが入ってるとまずいかと思ってみたりもしたのだけれど,抜いても同じだった.
QuartusIIがFitting(配置配線)を諦めたと考えるべきなのだろうか.そのわりにはそんなWarningらしきものは出てないようだしなぁ.この手のTipsてどこかに落ちてないのだろうか...
Warningゼロは不可能に近いことは承知しているが,SOPC Builderだけでペタペタ作ってこれだけWarningが出てくるのも怖いわけですよ.HDL真面目に触りだして短いのもあるけれど,CでいうならばWarningの理由を全て把握した上でないと,安心して出荷できないじゃないですか.
PerlでHDL記述を自動生成したりしているようだけれど,Verilogのビット幅指定を端折っていたりする.これでもWarningは出てくるのだけれど,こういう感じで理解しているものは無視できる.しかし,Timing errorを無視するわけにはいかないだろう….
妄想~要因の追求
ちなみに.
今回の発生箇所周辺をTechnology Map Viewer(Post-Fitting)で覗いてみた.エラー発生箇所は,外部からのJTAG信号を,ALTERAが開示していないIP(TAP controllerかな?)を介した後の信号で発生しているように見える.
removal timing errorの絵も理解できないので,それも問題なわけだが.hold time相当という理解なのだけれど,図示させてみるとこんな感じ.
launch edge/latch edgeともに,altera_reserved_tckなのだけれど,slack計算がわからん.
Data Arrival Pathが,非同期クリアに入っているので,Data Required Pathが入るときにhold timeが必要ということなのですよね.
tckのクロックは100nSec(10MHz)としているのだが,この8.808nSecというのは,非同期クリアのためのhold timeというわけか.
で,altera_internal_jtagの中身が全く見えないのが問題を切り分けられない要因.たしかにtckが入ってきているが,updateuser信号へも伝播しているのか.遅延時間が出ているからこのとおりか...だとすると,この部分の非同期リセットは保障されないということでF.A.?
では,何故Quartus IIは頑張ってFittingしようとしてくれないのか.つーか,制約満たせなくてもエラーで止まらないのか.
という感じで,ひきずりつつ今週終了\(^o^)/
2008/12/15(月)[SOPC] システムリセットについて
[Altera][SOPC][Q2HB] システムリセットについて
シミュレーション実施時に不定値が伝播したと書きましたが,SOPC上でのIPコアの設定が一部まずかったのが要因のようです.
結論に至る前に,そもそもPLLが安定するまでの間はどうなっているのかという疑問を払拭するために調べてみました.
そのメモをここに掲載しておきます.
前回の記事で注目していたのは,SOPC上でインスタンス化した,PLLとDDRSDRAM(HP)コントローラでした.それぞれについて確認しましょう.
PLL
資料の読み取りは,[Q2HB]PLLを参照ください.
仕様書にSOPC全域にリセット要求を発します,と明記してありました.
DDRSDRAM(HP)
DDRSDRAM(HP)のreset_request_n信号をどのように処理しているかを確認する.SOPC Builderが作ったファイルを開いて,DDR moduleのインスタンス化コードを参照し,そこから当該信号がどのnetにぶら下がっているかを確認する.
ddrsdram_s1_arbitratorに入力されているだけだったので,該当モジュールを見る.
module ddrsdram_s1_arbitrator ( input ddrsdram_s1_resetrequest_n; output ddrsdram_s1_resetrequest_n_from_sa; wire ddrsdram_s1_resetrequest_n_from_sa; //assign ddrsdram_s1_resetrequest_n_from_sa = ddrsdram_s1_resetrequest_n // so that symbol knows where to group signals which may go to master only, which is an e_assign assign ddrsdram_s1_resetrequest_n_from_sa = ddrsdram_s1_resetrequest_n;
ddrsdram_s1_resetrequest_n_from_saへ常時代入されていることがわかる.インスタンス化しているところに戻ると,この出力信号を束ねているところがある.
//reset sources mux, which is an e_mux assign reset_n_sources = ~(~reset_n | 0 | 0 | cpu_jtag_debug_module_resetrequest_from_sa | cpu_jtag_debug_module_resetrequest_from_sa | 0 | ~ddrsdram_s1_resetrequest_n_from_sa | ~ddrsdram_s1_resetrequest_n_from_sa | 0 | pll0_s1_resetrequest_from_sa | pll0_s1_resetrequest_from_sa);
reset_n_sourcesが,システム全体のリセット要求が無いことを確認する信号になっている模様(未検証).
//reset is asserted asynchronously and deasserted synchronously Nios2_NoDDR_reset_SysClk_domain_synch_module Nios2_NoDDR_reset_SysClk_domain_synch ( .clk (SysClk), .data_in (1'b1), .data_out (SysClk_reset_n), .reset_n (reset_n_sources) ); //reset is asserted asynchronously and deasserted synchronously Nios2_NoDDR_reset_osc_clk_domain_synch_module Nios2_NoDDR_reset_osc_clk_domain_synch ( .clk (osc_clk), .data_in (1'b1), .data_out (osc_clk_reset_n), .reset_n (reset_n_sources) );
osc_clk(FPGA外部からの唯一のクロック)を用いて,非同期リセット+同期リセット解除の信号SysClk_reset_n・osc_clk_reset_nを生成する.clock domainが複数存在するが,それぞれで同期化して出力している.
このリセット信号を誰が使っているのかを見ていくと...
ddrsdram the_ddrsdram ( .soft_reset_n (osc_clk_reset_n) pll0_s1_arbitrator the_pll0_s1 .reset_n (osc_clk_reset_n) Nios2_NoDDR_clock_0_out_arbitrator the_Nios2_NoDDR_clock_0_out .reset_n (osc_clk_reset_n)
ということで,各IPのリセット要求が解除されるまではシステムが停止する仕様になっています.DDR-SDRAMについては,PLL安定するまではリセット要求を出します.また,PLLのリセットを行わない,PHYだけのリセット要求入力に,同期化したシステムリセット要求信号が入ります.リセット解除の同期化は,どちらが先になるのかわからないので,厳密には一番遅い周期にあわせたウェイトを入れてやる必要があるのかもしれません.FIFOにリクエストを積み上げるのであれば,リセットタイミングが多少ずれても,Power on reset直後の値さえ合致していれば,レイテンシが少しかさむだけで問題なく動くでしょう.
結論
仕様解釈
IP側でPLL発振安定までの間に不定値が伝播するような問題はない.
→PLL lock待ちの回路も自作は不要.
ただし,ALTPLLの"locked"信号を出力する設定にしておくことが必要!!そのほか,ResetRequest信号が出ているIPについては,その出力を有効にしておく必要があるでしょう(未確認).
シミュレーション実施時に不定値が伝播した問題について
シミュレーション実施時には,PLL側の"locked"信号を出していなかったので,システムリセットがネゲートされていたと考えられます.*1
正しく?設定をすると,問題なくModelSIM WEB editionでFunction Simulationの実行ができました.