2012年4月30日月曜日

DoPをADATで

 DoPをADATで運用するためのFPGAの改造をGWの連休中に何とか立ち上げようと開始しました。


 以前 HQ Player  dCS方式DSDネイティブ出力が手持ちのDDCでも出来るか ということでこの時はSPDIFでの確認ですが、結果ノイズだらけで再生できずで頓挫してしまいましたが、いろいろ情報やツールも出揃ってきたので、ADATで再挑戦してみます。


 まずはADAT上のDoPのフォーマットについて...
 


ADAT SMUXのチャネルマッピング

 上図はADAT(SMUX)のPCMデータのマッピングです。ADATは伝送速は、11.2896Mbit/s(44.1kHz系列) or  12.288Mbit/s(48kHz系列) 固定で、44.1k/48kHz時は8ch、88.2k/96kHz時は、4ch、176.4k/192kHz時は、2chを伝送することが出来ます。
 ステレオで扱う場合、44.1k/48kHz時は4つのステレオチャネル(a,b,c,d chとします)をa_ch L/R,b_ch L/R,c_ch L/R d_ch L/Rという順序でチャネル割当されます。
  88.2k/96kHz時は、2つのステレオチャネル(a,b chとします)をa_ch L 2sample /a_ch R 2sample , b_ch L 2sample /b_ch R 2sample ,という順序でチャネル割当されます。
  176.4k/192kHz 時は、1つのステレオチャネル(a chとします)をa_ch L 4sample /a_ch R 4sample という順序でチャネル割当されます。


 DoPでDSD64を伝送する場合、176.4kHzのモードを使用します。



DoP DSD64のチャネルマッピングと受信後のフォーマット変換(*差替版)


1フレーム中のLch 4sample分の内、最初の1sampleの下位16bitをMSB側として、次の1sampleの 下位16bitをLSB側として32bitに連結し、FPGA内部バッファに書き込みます。その他も同様に2sample分の下位16bitを結合して32bit化してFPGA内部バッファに書き込みます。
 *上記でも問題なく処理できますが、DSD128と制御方法を揃えるため、Upper側16bit、Lower側16bitを個別にメモリへライトすることにしました。


 DoPでDSD128を伝送する場合、1本のADATラインでは伝送容量が不足するため、2つのADATラインを使います。各ラインは176.4kHzのモードを使用します。

DoP DSD128のチャネルマッピングと受信後のフォーマット変換 (*差替版)


1本でLchまたはRchを伝送します。ADAT 8chに順番にLchまたはRchの16bit×8コ分のデータが埋め込まれているので、 DoP DSD64の場合と同じルールで 2sample分の下位16bitを結合して32bit化してFPGA内部バッファに書き込みます。  Lch はUpper側16bitにRchはLower側16bitに個別に書込メモリ上で、整列させます。

 
 前回の時は、内部ではDoPのフォーマットのまま扱い、出力時にDSDフォーマットに変換する方式をとっていましたが、プレーンDSDの入出力とDoPの入出力を相互にうまく扱うには一旦DSD(メモリ格納時32bit化)して扱う方が、処理し易いと思われるので、入力側でDSD化するように変更することにしました。
 

2012年4月28日土曜日

MUSILAND Monitor 01 MINI  2

MUSILAND Monitor 01 MINI が到着。とりあえず、基板を見てみました。
DACにはTI PCM1781 が使用されています。このチップ24bit@192kHzまでは対応しているようで、I2SでFPGAと接続されていますので、容易に引き出せそうです。


    MUSILAND Monitor 01 MINI

   MUSILAND Monitor 01 MINI


  MUSILAND Monitor 01 MINI 基板 と BuffaloII


 MUSILAND Monitor 01 MINI 基板

MUSILAND Monitor 01 MINI  基板裏 


CYPRESS  CY7C68013A
  EZ-USB®FX2LP™USBマイクロコントローラハイスピー​​ドUSBペリフェラルコントローラ 

DAC ChipはTI PCM1781 

2012年4月26日木曜日

MUSILAND Monitor 01 MINI

 今まで気がついていませんでしたが、MUSILAND Monitor 01 MINIという小さいUSB DDC/DACを見つけました。昨年6月発売で、代理店のテックの通販はすでに売り切れになっています。
そのせいもあるのか、送料別ですが\5,000で販売しているところもあり購入してみました。


87×61×13mm と比較的小さく(といってもXMOSとほぼ同じ大きさっぽい)、24bit@192kHzまで対応しているので、モバイル向けのDoP用DDCベースにも良いかもしれません。中の基板を取り出してDACと同じケースにいれることも考えられます。



MUSILAND Monitor 01 MINI
MUSILAND Monitor 01 MINI 基板

2012年4月21日土曜日

PSoC 3本

シリーズ最強 ! PSoCボード + デバック・ボード 2012年 05月号を買ってみました。


 PSoCには興味はありましたが、新しいツールをマスタするのそれなりに大変ですし、あまり日本語マニュアルは充実していなさそうなので、とりかかりにはよさそうです。


 アナログ機能は今のところあまり必要としていませんが、比較的小さなボードであるのでモバイル向けに組み込むのに良さそうです。
 チップ単体でもSOICやDIPタイプのものが秋月で購入できるので、ボードを起こすのも比較的容易そうです。
 ロジック部のゲート数があまり大きくないのと、使い勝手がどうか次第では使いものにならないかもしれませんが...


シリーズ最強 ! PSoCボード + デバック・ボード 2012年 05月号




 プリント基板作りの基礎と実例集もパターン引き回しの参考書として一緒に購入しました。

JRiver Media Center DoP対応

 PCで音楽さんの記事でJRiver Media Centerがv 17.0.106  DoPに対応したことが紹介されています。
半月ぐらい前に試したときは未だ対応しておらず、そのままチェックしていませんでしたが、その後対応していたようです、
 v17.0.122をダウンロードしてインストール。今までライセンス未購入でしたが、特に問題なければ、メインで使用するつもりで購入してみました。

 JRiver Media Center

 DoPで使用するには、下記の設定を合わせればOK。
 DoPモードは見つけにくいところにあり ビデオ-bitstreaming にチェックボックスがあります。
 また、ASIOで試してみましたがダメでWASAPI-Event Styleでしかうまくいっていません。

 ビデオ-bitstreaming カスタムを選択し、DSD over PCM(DoP) をチェック
 DoP Format:使用機器に合わせてDoPかdCSを選択

 オーディオ-出力モード:WASAPI-Event Styleを選択
 出力モード選択で使用するデバイスを選択

2012年4月19日木曜日

Thunderbolt光ケーブル

住友電気工業がThunderbolt光ケーブルのサンプル出荷を開始したとのこと。
最大伝送距離は20mとのこと。意外と短いですね。

ケーブルコネクタ内に電気⇔光変換機能を実装し、コネクタは通常のメタルケーブルと同じで Thunderboltポートに挿せば使えるようになっています。

 下のBelkin のThunderbolt Express DockなどのThunderbolt⇔USB変換機能を持つ装置があれば、USB DDC/DACとPCの電源を完全にアイソレートすることが可能になるはずです。

  Belkin  Thunderbolt Express Dockは$299と少々お高いですが、だんだんとバリエーションも増え、価格もこなれてくるとを期待したいところです。
 光ケーブルの方は価格が不明ですが、それなりに高価になると思います。 
 Thunderboltポートを持つApollo High-Resolution Interfaceや、Apogee Symphony I/O 

Symphony 64 | ThunderBridgeなどのAudioIFもありますがやはり高価です。


 Thunderbolt光ケーブル(住友電気工業


 Belkin  Thunderbolt Express Dock 

2012年4月16日月曜日

QuartusII システムコンソール Dashboard 2

DashboardのGUIからFPGA内のレジスタアクセスする例として、I2Cコントローラのレジスタを周期モニタしてDashboardに表示させることと、Dashboardの設定用Textboxから設定する機能を作りこんでみました。

 システムコンソール Dashboard I2Cレジスタモニタ、設定画面



 "Start Mon"プッシュでレジスタを周期的に読みDashboardに表示し、TextBoxに設定値を書いて、setを押すとレジスタの内容が書きかえます。
 細かい調整や画面デザインなどはこれから。

 下記が該当部のtcl記述になります。

proc count_g3 {group_name} {

variable dash

variable prescale_val
variable control_val
variable status_val
variable transmit_val
variable receive_val
variable command_val
variable timer_val

#  reg read and display

set i2c_baseadd 0x00000000

set i2c_prescale       [format "0x%08x" [expr $i2c_baseadd + 0x0 ] ] 
set i2c_ctrl         [format "0x%08x" [expr $i2c_baseadd + 0x4 ] ] 
set i2c_status       [format "0x%08x" [expr $i2c_baseadd + 0x8 ] ] 
set i2c_transmit     [format "0x%08x" [expr $i2c_baseadd + 0xc ] ] 
set i2c_receive       [format "0x%08x" [expr $i2c_baseadd + 0x10 ] ] 
set i2c_command       [format "0x%08x" [expr $i2c_baseadd + 0x14 ] ]
set i2c_timer       [format "0x%08x" [expr $i2c_baseadd + 0x40 ] ]

   set mast [lindex [get_service_paths master] 0]
   open_service master $mast
   # prescale
   set prescale_val [master_read_32 $mast $i2c_prescale 1]  
   dashboard_set_property $dash $group_name.prer_val text [format "0x%04x" [expr ($prescale_val)] ]
   # ctrl
   set control_val [master_read_32 $mast $i2c_ctrl 1]  
   dashboard_set_property $dash $group_name.ctrl_val text [format "0x%04x" [expr ($control_val)] ]
   # status 
   set status_val [master_read_32 $mast $i2c_status 1]  
   dashboard_set_property $dash $group_name.status_val text [format "0x%04x" [expr ($status_val)] ]
   # transmit
   set transmit_val [master_read_32 $mast $i2c_transmit 1]  
   dashboard_set_property $dash $group_name.transmit_val text [format "0x%04x" [expr ($transmit_val)] ]
   # receive
   set receive_val [master_read_32 $mast $i2c_receive 1]  
   dashboard_set_property $dash $group_name.receive_val text [format "0x%04x" [expr ($receive_val)] ]
   # command
   set command_val [master_read_32 $mast $i2c_command 1]  
   dashboard_set_property $dash $group_name.command_val text [format "0x%04x" [expr ($command_val)] ]
   # timer
   set timer_val [master_read_32 $mast $i2c_timer 1]  
   dashboard_set_property $dash $group_name.timer_val text [format "0x%04x" [expr ($timer_val)] ]
   
   after 1000 i2c_Control::count_g3 $group_name
 }

 proc set_prer {group_name} {

variable dash
variable set_prescale_val

set i2c_baseadd 0x00000000
set i2c_prescale       [format "0x%08x" [expr $i2c_baseadd + 0x0 ] ] 

   set mast [lindex [get_service_paths master] 0]
   open_service master $mast
   
   set set_prescale_val [format "0x%04x" [dashboard_get_property $dash $group_name.prer_wr_val text]]
   master_write_32 $mast $i2c_prescale $set_prescale_val
 }

 proc set_tx {group_name} {

variable dash
variable set_tx_val

set i2c_baseadd 0x00000000
set i2c_transmit     [format "0x%08x" [expr $i2c_baseadd + 0xc ] ] 

   set mast [lindex [get_service_paths master] 0]
   open_service master $mast
   
   set set_tx_val [format "0x%04x" [dashboard_get_property $dash $group_name.tx_wr_val text]]
   master_write_32 $mast $i2c_transmit $set_tx_val
 }

# gen_group3
#
proc gen_group3 { { group_name "myTab.g3" } } {
variable dash

dashboard_add $dash $group_name  group myTab
dashboard_set_property $dash $group_name itemsPerRow 2

# read reg 
#prer reg
dashboard_add $dash $group_name.prer label $group_name
dashboard_set_property $dash $group_name.prer text "Clock Prescale"
dashboard_set_property $dash $group_name.prer preferredWidth 30

dashboard_add $dash $group_name.prer_val label $group_name
dashboard_set_property $dash $group_name.prer_val text "-"
dashboard_set_property $dash $group_name.prer_val preferredWidth 30

#ctrl reg
dashboard_add $dash $group_name.ctrl label $group_name
dashboard_set_property $dash $group_name.ctrl text "Control"
dashboard_set_property $dash $group_name.ctrl preferredWidth 30

dashboard_add $dash $group_name.ctrl_val label $group_name
dashboard_set_property $dash $group_name.ctrl_val text "-"
dashboard_set_property $dash $group_name.ctrl_val preferredWidth 30

#status reg
dashboard_add $dash $group_name.status label $group_name
dashboard_set_property $dash $group_name.status text "Status"
dashboard_set_property $dash $group_name.status preferredWidth 30

dashboard_add $dash $group_name.status_val label $group_name
dashboard_set_property $dash $group_name.status_val text "-"
dashboard_set_property $dash $group_name.status_val preferredWidth 30

#transmit reg
dashboard_add $dash $group_name.transmit label $group_name
dashboard_set_property $dash $group_name.transmit text "Transmit"
dashboard_set_property $dash $group_name.transmit preferredWidth 30

dashboard_add $dash $group_name.transmit_val label $group_name
dashboard_set_property $dash $group_name.transmit_val text "-"
dashboard_set_property $dash $group_name.transmit_val preferredWidth 30

#receive reg
dashboard_add $dash $group_name.receive label $group_name
dashboard_set_property $dash $group_name.receive text "Receive"
dashboard_set_property $dash $group_name.receive preferredWidth 30

dashboard_add $dash $group_name.receive_val label $group_name
dashboard_set_property $dash $group_name.receive_val text "-"
dashboard_set_property $dash $group_name.receive_val preferredWidth 30

#command reg 
dashboard_add $dash $group_name.command label $group_name
dashboard_set_property $dash $group_name.command text "Command"
dashboard_set_property $dash $group_name.command preferredWidth 30

dashboard_add $dash $group_name.command_val label $group_name
dashboard_set_property $dash $group_name.command_val text "-"
dashboard_set_property $dash $group_name.command_val preferredWidth 30

#timer reg
dashboard_add $dash $group_name.timer label $group_name
dashboard_set_property $dash $group_name.timer text "Timer"
dashboard_set_property $dash $group_name.timer preferredWidth 30

dashboard_add $dash $group_name.timer_val label $group_name
dashboard_set_property $dash $group_name.timer_val text "-"
dashboard_set_property $dash $group_name.timer_val preferredWidth 30

# button 
dashboard_add $dash $group_name.bstart button $group_name
dashboard_set_property $dash $group_name.bstart text "Start Mon"
dashboard_set_property $dash $group_name.bstart onClick  "i2c_Control::count_g3  $group_name"


# reg edit
#prer reg
dashboard_add $dash $group_name.prer_wr label $group_name
dashboard_set_property $dash $group_name.prer_wr text "Clock Prescale"
dashboard_set_property $dash $group_name.prer_wr preferredWidth 30

dashboard_add $dash $group_name.prer_wr_val textField $group_name
dashboard_set_property $dash $group_name.prer_wr_val preferredWidth 60
 
dashboard_add $dash $group_name.prer_set button $group_name
dashboard_set_property $dash $group_name.prer_set text "Set"
dashboard_set_property $dash $group_name.prer_set onClick  "i2c_Control::set_prer $group_name"

dashboard_add $dash $group_name.null label $group_name

#transmit reg
dashboard_add $dash $group_name.tx_wr label $group_name
dashboard_set_property $dash $group_name.tx_wr text "Transmit"
dashboard_set_property $dash $group_name.tx_wr preferredWidth 30

dashboard_add $dash $group_name.tx_wr_val textField $group_name
dashboard_set_property $dash $group_name.tx_wr_val preferredWidth 60
 
dashboard_add $dash $group_name.tx_set button $group_name
dashboard_set_property $dash $group_name.tx_set text "Set"
dashboard_set_property $dash $group_name.tx_set onClick  "i2c_Control::set_tx $group_name"

}



2012年4月15日日曜日

DSD to PCM Converter 2

DSD to PCM Converterdで書いた、 YUKI-SAN の DSD to PCM Converter AES/EBUなどサンプリングレート352.8kHzをサポートしない規格のための、MSB8bitコード 0x09/0xF9を用いる代替規格の0x09/0xF9のコード挿入パターンの違いについて、早々に対応していただきました。ありがとうございます。


 私の想定と同じで、各ch毎に0x09/0xF9パターンを繰り返すようになっています。


 Waveファイル 先頭部分
上:DSD128_DoP(0x06/0xF9)- DSD to PCM Converter Version 0.0.12
下:DSD128_DoP(0x06/0xF9)- DSD to PCM Converter Version 0.0.13

2012年4月14日土曜日

DSD to PCM Converter

YUKI-SAN の DSD to PCM Converterが DSD128のDoP(DSD over PCM)をサポートし、AES/EBUなどサンプリングレート352.8kHzをサポートしない規格のための、MSB8bitコード 0x09/0xF9を用いるへの代替規格もサポートしてくれました。



左:DSD64_DoP(0x05/0xFA)  中:DSD128_DoP(0x05/0xFA) 右:DSD128_DoP(0x06/0xF9) 
WaveファイルのRIFFタグ情報 

 まだ、DSD128_DoP(0x06/0xF9)を試す環境が準備できていませんが、とりあえずフォーマットを確認するため、DSD64のデータを、DSD64_DoP(0x05/0xFA) へと、AudioGateでDSD128に変換して、 DSD128_DoP(0x05/0xFA)、DSD128_DoP(0x06/0xF9)に変換してみました。
 上記がRIFFタグ情報を覗いてみた様子です。DSD128_DoP(0x05/0xFA)では、2チャンネル、352.8kHz、24bitのwaveファイルとなっています。DSD128_DoP(0x06/0xF9)では、4チャンネル、176.4kHz、24bitのwaveファイルとなっています。


Waveファイル 先頭部分
上:DSD128_DoP(0x06/0xF9) 
中:DSD128_DoP(0x05/0xFA)
下:DSD64_DoP(0x05/0xFA) 

 つぎにデータ部を見てみます。上が、DSD128_DoP(0x06/0xF9)、DSD128_DoP(0x05/0xFA) DSD64_DoP(0x05/0xFA) のデータの先頭部分です。
 0x00002Bまでが、タグ情報で、0x00002Cからがデータ部になっているようです。

  オレンジでハッチングしているのは、DSD128でのLchデータと思われる部分の先頭から20byte分になります。 
 0x05/0xFA方式では、16bit毎にL/Rchが埋め込まれています。
 0x06/0xF9方式では、32bir毎にL/Rchが埋め込まれています。

 これは、4chマルチチャネルのWaveファイルの1番目と2番目のチャネルにLchを、3番目と4番目のチャネルにRchを埋め込んでいるためで、これでDoPの規定に合っていると推測します。


  水色、黄色でハッチングしているのが、0x05/0xFAあるいは0x06/0xF9のコード、0x05/0xFA方式の場合は、DSDデータ16bit- 0x05 - DSDデータ16bit - 0xFAの順序で埋め込まれています。
 0x06/0xF9方式の場合も、DSDデータ16bit- 0x06 - DSDデータ16bit - 0xF9の順序で埋め込まれています。
 
 こちらは、少し私の推測と異なります。 0x06/0xF9方式の場合、4chの各chで0x06/0xF9を交互に埋め込むのではと推測しています。(あまり自信はありません...)

2012年4月12日木曜日

QuartusII システムコンソール Dashboard

システムコンソールのGUI機能、Dashboardの習得のため、DailとTimeChartで、FPGA内に作った32bit Timerカウンタを読みだして表示させてみました。

 Dashboardでは、これ以外にも Label, Text, Button, checkBox, LED, ComboBox, Table, BarChart, LineChart, PiChartなどが使えます。



システムコンソール Dashboard

上記Dashboardの表示Tabに関するTclは下記

namespace eval i2c_Control {

variable dash [add_service dashboard i2c_Control "I2C Control" "Tools/Dashboard"]

dashboard_set_property $dash self developmentMode true
dashboard_set_property $dash self itemsPerRow 1


# count g2 
proc count_g2 {group_name} {


variable dash
variable g2_cnt_val
variable g2_cnt_en


#  Timer read and display dail and chart
if { $g2_cnt_en } {


   set mast [lindex [get_service_paths master] 0]


   open_service master $mast


 # 0x40番地の32bit Timer counterをリードし、g2_cnt_valにセット    
   set g2_cnt_val [master_read_32 $mast 0x040 1]


  # dialへの読み取ったカウント値のセット
   dashboard_set_property $dash $group_name.dial value [expr ($g2_cnt_val /10000000)]
  # timechartへの読み取ったカウント値のセット
   dashboard_set_property $dash $group_name.tchart latest [expr ($g2_cnt_val /1000000)]

   after 1000 i2c_Control::count_g2 $group_name
   }
 }


# gen_group2 


proc gen_group2 { { group_name "myTab.g2" } } {
variable dash


dashboard_add $dash $group_name  group myTab
dashboard_set_property $dash $group_name itemsPerRow 1


# dial
dashboard_add $dash $group_name.dial dial $group_name
dashboard_set_property $dash $group_name.dial title "Dial_fpga"
dashboard_set_property $dash $group_name.dial min 0
dashboard_set_property $dash $group_name.dial max 440
dashboard_set_property $dash $group_name.dial preferredWidth 300
dashboard_set_property $dash $group_name.dial preferredHeight 300
dashboard_set_property $dash $group_name.dial value 0
  
# timechart
dashboard_add $dash $group_name.tchart timeChart $group_name
dashboard_set_property $dash $group_name.tchart title "Time chart"
dashboard_set_property $dash $group_name.tchart preferredWidth 800
dashboard_set_property $dash $group_name.tchart labelX "Time"
dashboard_set_property $dash $group_name.tchart labelY "Counter value"
dashboard_set_property $dash $group_name.tchart latest 0
  
# button to start the counter
dashboard_add $dash $group_name.bstart button $group_name
dashboard_set_property $dash $group_name.bstart text "Start counter"
dashboard_set_property $dash $group_name.bstart onClick  "set i2c_Control::g2_cnt_en 1; dashboard_set_property $dash  $group_name.bstart enabled false; dashboard_set_property $dash  $group_name.bstop enabled true; i2c_Control::count_g2  $group_name"
 
# button to stop the counter
dashboard_add $dash $group_name.bstop button $group_name
dashboard_set_property $dash $group_name.bstop text "Stop counter"
dashboard_set_property $dash $group_name.bstop enabled false
dashboard_set_property $dash $group_name.bstop onClick   "set i2c_Control::g2_cnt_en 0; dashboard_set_property $dash  $group_name.bstart enabled true; dashboard_set_property $dash  $group_name.bstop enabled false"
}

# tabbedGroup


dashboard_add $dash myTab tabbedGroup self
dashboard_set_property $dash myTab preferredWidth 1024
dashboard_set_property $dash myTab preferredHeight 700


# Create Grourps


gen_group1 "Dial"
gen_group2 "Counter_fpga"
#gen_group3 "I2C_Control"
}

2012年4月8日日曜日

DSD Over PCM標準規格1.1 DSD128サポート

Music TO GO!さんでDSD Over PCM標準規格が1.1に更新してDSD128をサポートしたことが紹介されています。
dCS方式と書いていましたが、この言い方は改めて今後はDoP(DSD Over PCM)と言ったほうがよさそうです。今後はDoPと書くようにします。

DoP open Standard Method for transferring DSD Audio over PCM Frames  Version 1.1

 うれしいことにAES/EBU等384kHzのPCMを標準ではサポートしないインタフェースでのDSD128のサポート方法もSolution2として規格化してくれています。
要は、192kHz@24bitのライン1本でDSDの1ch(LchもしくはRch)を載せ、2本でDSD128のL/Rペアをサポートするインタフェースということになります。

MarkerはSolution1の0x05/0xFAオルタネートとは異なり、0x06/0xF9のオルタネートパターンになり、AES/EBUなどのLch/Rchに交互に16bitの1ch分のDSDデータを入れる方式のようです。

据え置きのPCとのオーディオインタフェースはUSBではなく、電源完全分離が可能な光インタフェース(ADAT RME RayDAT)を使用をメインに想定しているので、もし規格化されなくとも、同じ事をなんとか実現することを考えていましたが、規格化されたので対応する再生ソフトが順次出てくると思いますので、非常にラッキーです。


また、サポートメンバーにCEntranceが加わったとのこと、XMOS用のCEntrance ASIOドライバは極性現状反転処理が入っていてビットパーフェクトになっていないようなのですが、これでCEntranceのドライバも使えるようになると思われます。

2012年4月7日土曜日

QuartusII システムコンソール

クロックボードのClock Synthesizer TI CDCE913のI2Cの制御ですが、Arduinoを考えていましたが、今後のこともあるのでFPGAにマスタ機能を実装して制御することに方針変更。

I2CマスタのRTLは、OpenCores.orgにあるWISHBONEバス用I2CマスタverilogコードをベースにAvalonMM スレーブインタフェースに変更、systemverilogコード化等を施しました。

さて、QuartusIIの新しい機能にシステムコンソールという機能があり、PCからFPGAのメモリ、レジスタのリード.ライトアクセスや、ボタン、ダイヤル、グラフなどのGUI 機能にさまざまなシステム・レベル・トランザクションを追加し、データ処理をモニタリングするカスタム検証ツールやデモ・ツールを比較的簡単に作ることができます。

この機能を使って、PCからI2Cのアクセス制御や、ES9018のレジスタをGUI制御することに挑戦してみたいと思います。

先ずはQurtusIIをV11.1sp2にバージョンアップ。ディスク容量(64G SSD)が限界だったMusicPCにSSD128Gbyte(128GB Crucial m4 2.5-inch SATA 6GB/s)に新調し、MusicPCの方にインストールしてみました。
しかし何故かUSB Blaster(実際にはDE0-nano)を認識してくれません。Windows7 Ultimate 64bitマシンなのですが、原因は今のところ不明。仕方が無いので、メインマシンの方にもインストールすることに...


システムコンソールとI2Cマスタの機能確認用に、先ずはI2CコントローラとJtag to Avalon Master Bridge のみのQsysモジュールを作成。今までSOPCビルダーを使っておりQsysを使うのも初めてになります。


 I2CコントローラとJtag to Avalon Master Bridge のみのQsysモジュール


以下、簡単にSystemControlによるレジスタのリード/ライトを行う手順をリストします。



1. 上記のQsysとI2CマスタモジュールをDE0-nanoに実装してコンパイルし、DE0-nanoにコンフィグ

2. QsysのウインドウからTools-System ConsoleでSystem Consoleを起動。

3. System Console Files-Load Design....で開くウインドで、qpfファイル(今回の場合DE0-Nano.qpf)を選択し"開く"をクリック



  システムコンソール

4. JTAG Avalon Master Bridge の提供するJtag debug serviceの場所の指定 

 % set jtag_debug [ lindex [ get_service_paths jtag_debug ] 0 ]
 /devices/EP3C25|EP4CE22@1#USB-0/(link)/JTAG/(110:132 v1 #0)/phy_0

 


5. リセット解除の確認
 % jtag_debug_sample_reset $jtag_debug  
 1

/* jtag_debug_sample_reset <service-path> 
     Returns the value of the reset_n signal of the Avalon-ST 
JTAG Interface core. If reset_n is low (asserted), the value 
is 0 and if reset_n is high (deasserted), the value is 1.  */


6.クロックがトグルしているかの確認 (何度か繰り返し”1""0"両方が表示されるとトグルしている)
 % jtag_debug_sample_clock $jtag_debug
 1    

/*jtag_debug_sample_clock <service-path>
Returns the value of the clock signal of the system clock that drives the module's system interface. The clock value is sampled asynchronously; consequently, you may need to sample the clock several times to guarantee that it is toggling. */


7.もうひとつのクロック確認手段(リセット中にクロックが数回トグルすると"1"が表示される)
 % jtag_debug_sense_clock $jtag_debug
 1    

/*jtag_debug_sense_clock  <service-path>
Returns the result of a sticky bit that monitors for system clock activity. If the clock has toggled since the last execution of this command, the bit is 1. Returns true if the bit has ever toggled and otherwise returns false. The sticky bit is reset to 0 on read. */

8.Jtag Avalon master のパスを見つける
 % get_service_paths master
 /devices/EP3C25|EP4CE22@1#USB-0/(link)/JTAG/(110:132 v1 #0)/phy_0/master}   

/* get_service_paths <service_type_name>

Returns a list of paths to nodes that implement the requested service type.
Note: When this command returns an item in the list that has only one element and the element has no spaces in it, you should not pass the element to other commands.
As an example, do not run this command: 
set master [ get_service_paths master ] master_read_memory $master 0x0200 16
Instead, please run this command:
set masters [ get_service_pathsmaster ]
set master [ lindex $master 0 ] master_read_memory $master 0x0200 16 */

9.マスターを指定
 % set master [ lindex [get_service_paths master] 0 ]
 /devices/EP3C25|EP4CE22@1#USB-0/(link)/JTAG/(110:132 v1 #0)/phy_0/master 

10.ライトアクセス(32bit)
 % master_write_32 $master 0x000 0x1234


/* master_write_32 <service-path> <address><list_of_32_bit_words>
Writes the list of 32-bit values, starting at the specified base address, using 32-bit accesses.*/


11.リードアクセス
 % master_read_32 $master 0x000 4
 0x00001234 0x00000000 0x00000000 0x00000000  


/* master_read_32 <service-path> <base_address> <size_in_multiples_of_32_bits>
Returns a list of <size> 32-bit bytes. Read from memory starts at the specified base address, using 32-bit accesses.*/