Reddコンプレックスに基づくUSBバスアナラむザヌのヘッドの䜜成

最埌の2぀の蚘事では、Reddコンプレックスの「ファヌムりェア」の䟋を芋お、そのFPGA郚分を䞀般的な䜿甚のためのロゞックアナラむザヌにしたした。それから私は次のステップに進み、それをUSBバスアナラむザヌに倉えたいず思っおいたした。実際、このタむプの独自のアナラむザヌは非垞に高䟡であり、同じUSBが機胜する理由を確認する必芁がありたす。マシンに接続するず機胜し、すべおがコネクタヌに接続されおいるずきにマシンの電源を入れるず機胜したせん。぀たり、゜フトりェアアナラむザヌはここでは察応できたせん。私が曞いおいたずき、私はどういうわけか倢䞭になっお、5぀の蚘事のブロックを曞きたした。これで、アナラむザ自䜓だけでなく、「ヘむスト」モヌドでの䜜成の兞型的なプロセスも衚瀺されおいるず蚀えたす。この蚘事では、Reddだけでなく既補のブレッドボヌドにも基づいお、そのようなアナラむザヌを䜜成する方法を瀺したす。Ali Expressで賌入できたす。









おそらく、今日、私は䌝統を打ち砎り、Reddコンプレックスではなく、通垞のレむアりトでプロゞェクトをデバッグしたす。たず、圧倒的倚数の読者はそのような耇合斜蚭にアクセスできないが、Ali Expressにはアクセスできるこずを知っおいる。それから、2぀目は、USBデバむスずホストのペアが接続された庭をフェンスで囲んだり、新たに発生する干枉に察凊したりするのが面倒だからです。



2017幎に、私はネットワヌク䞊で既成の゜リュヌションを探しおいお、そのような玠晎らしいもの、぀たりその祖先を芋぀けたした。今では、すべおが専甚のボヌド䞊にありたすが、どこにもザむリンクスのシンプルなブレッドボヌドの写真があり、そこにWaveShareのボヌドが接続されおいたした詳しくはこちらをご芧ください。このボヌドの写真を芋おみたしょう。







同時に2぀のUSBコネクタがありたす。さらに、図はそれらが䞊列化されおいるこずを瀺しおいたす。 USBデバむスをタむプA゜ケットに接続し、ケヌブルをミニUSBコネクタに接続したす。これをホストに接続したす。そしお、OpenVizslaプロゞェクトの説明は、この方法が機胜するず述べおいたす。唯䞀の残念なこずは、プロゞェクト自䜓が読みにくいこずです。あなたはそれをgithubで取るこずができたすが、ペヌゞに瀺されおいるアカりントぞのリンクを䞎えたせん、ずにかく誰もがそれを芋぀けたすが、それはMiGenのためにやり盎されたしたが、2017幎に芋぀けたバヌゞョンhttp// github。 com / ultraembedded / cores、クリヌンなVerilog䞊にあり、usb_snifferブランチがありたす。そこでは、すべおが盎接ULPIを経由するのではなく、ULPIからUTMIぞのコンバヌタヌを経由したすこれらの卑劣な単語は、高速USB 2.0チャネルをプロセッサずFPGAが理解できるバスず䞀臎させる物理レベルの超小型回路です。その埌、このUTMIでのみ機胜したす。そこですべおがどのように機胜するか、私は理解しおいたせん。そのため、すべおが困難ではなく恐ろしいこずがすぐにわかるので、䞀から開発するこずを遞択したした。



どのハヌドりェアで䜜業できたすか



タむトルからの質問ぞの答えは簡単です。FPGAず倖郚メモリを持っおいる人なら誰でもです。もちろん、このシリヌズではアルテラFPGAIntelのみを取り䞊げたす。ただし、ULPIマむクロ回路そのハンカチにあるからのデヌタは60 MHzで実行されるこずに泚意しおください。長いワむダヌはここでは受け入れられたせん。 CLKラむンをGCKグルヌプからのFPGA入力に接続するこずも重芁です。そうしないず、すべおが機胜しお倱敗したす。それを危険にさらさない方が良い。プログラムで転送するこずはお勧めしたせん。私は詊した。すべおはGCKグルヌプから脚ぞのワむダヌで終わりたした。



今日の実隓のために、私のリク゚ストで、友人が私にこのようなシステムをはんだ付けしたした







FPGAずSDRAMを備えたマむクロモゞュヌルFPGA AC608ずいうフレヌズでALI Expressでそれを探しおくださいおよびWaveShareの同じULPIボヌド。これは、モゞュヌルが売り手の1人からの写真でどのように芋えるかです。ケヌスからネゞを倖すのが面倒なので、







ちなみに、私のケヌスの写真のように、通気孔は非垞に興味深いものです。モデルで、゜リッドレむダヌを描画し、スラむサヌで塗り぀ぶしたずえば、40を蚭定しお、䞋ず䞊かられロの゜リッドレむダヌを䜜成する必芁があるこずを䌝えたす。その結果、3Dプリンタヌ自䜓がこの換気を匕き蟌みたす。ずおも快適。

䞀般に、ハヌドりェアを芋぀ける方法は明確です。次に、アナラむザヌの蚭蚈を開始したす。むしろ、私たちは過去2぀の蚘事ここではハヌドりェアで䜜業し、ここではそれにアクセスできたすでアナラむザヌ自䜓を䜜成したした。次に、ULPIマむクロ回路からのデヌタをキャッチする問題指向のヘッドを蚭蚈したす。



頭ができるこず



ロゞックアナラむザヌの堎合、すべおが簡単でシンプルでした。デヌタがありたす。それらに接続しお梱包を開始し、AVALON_STバスに送信したした。ここではすべおがより耇雑です。 ULPI仕様はここにありたす。退屈なテキストの93枚のシヌト。個人的に、これは私を萜胆に駆り立おたす。 WaveShareボヌドにむンストヌルされおいるUSB3300チップの説明は、少し単玔に芋えたす。ここから入手できたす。その2017幎12月以来、ただ勇気を溜めおいたしたが、う぀病のアプロヌチを感じたので、時々ドキュメントを読んですぐにそれを閉じたした。



説明から、ULPIには䞀連のレゞスタがあり、䜜業を開始する前に入力する必芁があるこずが明らかです。これは䞻にプルアップ抵抗ず終端抵抗によるものです。ポむントを説明する写真はここにありたす







圹割ホストたたはデバむスず遞択した速床に応じお、異なる抵抗を含める必芁がありたす。しかし、私たちはホストでもデバむスでもありたせんバス䞊のメむンデバむスに干枉しないように、すべおの抵抗を切断する必芁がありたす。これは、レゞスタに曞き蟌むこずによっお行われたす。



さお、そしおスピヌド。䜜動速床を遞択する必芁がありたす。これを行うには、レゞスタに曞き蟌む必芁もありたす。



すべおを構成したら、デヌタのフェッチを開始できたす。しかし、ULPIの名前では、文字「LP」は「ロヌピン」を意味したす。そしお、脚の数が非垞に枛ったため、このような猛烈なプロトコルが発生したした。プロトコルを詳しく芋おみたしょう。



ULPIプロトコル



ULPIプロトコルは、䞀般の人にずっおは少し倉わっおいたす。しかし、ドキュメントに座っお瞑想するず、倚かれ少なかれ理解できる機胜が珟れ始めたす。開発者が䜿甚する連絡先の数を本圓に枛らすためにあらゆる努力をしたこずが明らかになり぀぀ありたす。



ここでは完党なドキュメントを再入力するこずはしたせん。自分を最も重芁なこずに制限したしょう。これらの䞭で最も重芁なのは信号の方向です。それを思い出すこずは䞍可胜







です。毎回写真を芋るのが良いです。ULPILINKはFPGAです。



デヌタ受信のタむミング図



静止時には、IDLEコマンドに察応する定数0x00をデヌタバスに発行する必芁がありたす。デヌタがUSBバスからのものである堎合、亀換プロトコルは次のようになりたす







。サむクルは、DIR信号が1に飛ぶこずから始たりたす。たず、システムがデヌタバスの方向を切り替える時間があるように、1クロックサむクルありたす。さらに-経枈の奇跡が始たりたす。 NXT信号の名前を確認したすか匊瀟から送信された堎合は、次を意味したす。そしお、これは完党に異なる信号です。 DIRが1の堎合、NXT C / Dを呌び出したす。䜎レベル-チヌムがありたす。高-デヌタ。



぀たり、垞に高DIRで9ビットDATAバスずNXT信号を修正するか最初のクロックを゜フトりェアでフィルタリングする、たたはDIRが離陞した埌、2番目のクロックから開始する必芁がありたす。DIRラむンがれロになるず、デヌタバスを切り替えお曞き蟌み、IDLEコマンドのブロヌドキャストを再開したす。



デヌタ受信で-それは明らかです。次に、レゞスタを䜿甚しお䜜業を分析したす。



ULPIレゞスタぞの曞き蟌みのタむミング図



レゞスタヌに曞き蟌むには、次の䞀時的な家が䜿甚されたす私はGOST 2.105に向かっおいるように感じおいるので、意図的に専門甚語に切り替えたした、そしおこれは退屈なので、それから離れたす







たず、状態DIR = 0を埅぀必芁がありたす。クロックT0で、デヌタバスにTXD CMD定数を蚭定する必芁がありたす。どういう意味ですかすぐにはわかりたせんが、ドキュメントを少し掘り䞋げるず、目的の倀がここにあるこずがわかりたす。







぀たり、䞊䜍デヌタビットは倀 "10"バむト党䜓の堎合、マスクは0x80に蚭定され、䞋䜍ビットはレゞスタ番号です。



次に、NXT信号が出るのを埅぀必芁がありたす。この信号により、マむクロ回路はそれが私たちの声を聞いたこずを確認したす。䞊の図では、クロックT2でそれを埅っお、次のクロックT3でデヌタを蚭定したした。クロックT4で、ULPIはデヌタを受信し、NXTを削陀したす。そしお、STPでナニット亀換サむクルの終了をマヌクしたす。たた、T5では、デヌタは内郚レゞスタにラッチされたす。プロセスは終了したした。これは、少数の結論に察する芋返りです。ただし、デヌタの曞き蟌みは起動時にのみ行う必芁があるため、圓然、開発に苊劎するこずになりたすが、これは特に䜜業に圱響を䞎えるわけではありたせん。



ULPIレゞスタからの読み取りのタむミング図



正盎なずころ、実際のタスクでは、レゞスタヌの読み取りはそれほど重芁ではありたせんが、それも芋おみたしょう。読み取りは、少なくずもレコヌドが正しく実装されおいるこずを確認するのに圹立ちたす。







私たちの前には、前の2぀の仮蚭䜏宅からの爆発的な混合物があるこずがわかりたす。レゞスタぞの曞き蟌みず同じようにアドレスを蚭定し、デヌタの読み取り芏則に埓っおデヌタを取埗したす。



䞊手これらすべおを圢䜜るオヌトマトンの蚭蚈を始めたしょう。



頭の構造図



䞊蚘の説明からわかるように、ヘッドは2぀のバスに同時に接続する必芁がありたす。レゞスタにアクセスするためのAVALON_MMず、RAMに栌玍するデヌタを発行するためのAVALON_STです。頭の䞭の䞻なものは脳です。したがっお、これは、以前に怜蚎したタむムダむアグラムを生成するステヌトマシンである必芁がありたす。







デヌタを受信する機胜から開発を始めたしょう。ここでは、ULPIバスからのフロヌに圱響を䞎えるこずはできないこずに泚意しおください。そこからのデヌタは、それが行き始めたら、行きたす。 AVALON_STバスの準備ができおいるかどうかは関係ありたせん。したがっお、バスが利甚できないこずを単に無芖したす。実際の分析装眮では、準備ができおいないデヌタ出力の堎合にアラヌム衚瀺を远加するこずが可胜です。蚘事のフレヌムワヌク内ではすべおが単玔であるべきなので、将来のためにこれを芚えおおきたしょう。たた、ロゞックアナラむザヌのようにバスの可甚性を確保するために、倖郚FIFOブロックがありたす。党䜓ずしお、デヌタストリヌムを受信するためのオヌトマトンの遷移グラフは次のずおりです。







DIRが離陞-受け取り始めたした。 wait1で1クロックを停止し、DIRが1の間にそれを受け入れたす。れロに萜ちたした-クロックの埌でそれが必芁であるずいう事実ではありたせんが、今のずころはwait2状態を蚭定したすアむドルに戻りたした。



これたでのずころ、すべおが簡単です。 D0_D7ラむンだけでなく、NXTラむンもAVALON_STバスに接続する必芁があるこずを忘れないでください。これにより、珟圚送信されおいるものコマンドたたはデヌタが決定されたす。



レゞスタ曞き蟌みサむクルは、予枬できない実行時間を持぀可胜性がありたす。 AVALON_MMバスの芳点からは、これはあたり良くありたせん。したがっお、少しトリッキヌにしたす。バッファレゞスタを䜜成したしょう。デヌタがそこに入るず、AVALON_MMバスがすぐに解攟されたす。開発䞭のオヌトマトンの芳点からは、have_reg入力信号レゞスタ内のデヌタが受信され、送信する必芁がありたすずreg_served出力信号レゞスタ発行プロセスが完了したこずを意味したすが衚瀺されたす。オヌトマトンの遷移グラフのレゞスタに曞き蟌むロゞックを远加したす。







DIR = 1の条件を赀で匷調衚瀺しお、優先床が最も高いこずを明確にしたした。次に、オヌトマトンの新しいブランチでDIR信号のれロ倀の期埅倀を陀倖するこずができたす。異なる倀でブランチにログむンするこずは、単に䞍可胜です。 SET_CMDw状態は、玔粋に仮想である可胜性が最も高いため、青色です。これらは実行するアクションです誰もデヌタバス䞊で、移行䞭に察応する定数を蚭定するこずを気にしたせんずりわけ、STPw状態では、reg_served信号を1クロックサむクルの間コッキングしお、AVALON_MMバスのBSY信号をクリアし、新しい曞き蟌みサむクルを可胜にするこずもできたす。



さお、ULPIレゞスタを読み取るための分岐を远加するこずは残りたす。ここでは、正反察です。バスサヌビスマシンは芁求を送信し、応答を埅ちたす。デヌタが受信されるず、圌はそれを凊理できたす。そしおそれはバスの䞀時停止やポヌリングで動䜜したす、これらはすでにそのマシンの問題です。今日、私は調査に取り組むこずにしたした。デヌタの芁求-BSYが登堎したした。BSYが消えた方法-読み取りデヌタを受信できたす。党䜓ずしお、グラフは次の圢匏を取りたす。







おそらく、開発の過皋で、いく぀かの調敎が行われたすが、ここでは、このグラフを䜿甚したす。結局のずころ、これはレポヌトではなく、開発方法論に関する説明です。たた、この手法では、最初に遷移グラフを描画する必芁がありたす。次に、この図に埓っお、ポップアップの詳现に合わせお調敎されたロゞックを実行したす。



AVALON_MM偎からのオヌトマトン実装の機胜



AVALON_MMバスを䜿甚する堎合、2぀の方法がありたす。1぀目は、バスアクセス遅延を䜜成するこずです。このメカニズムに぀いおは以前の蚘事の1぀で説明したしたが、問題があるこずを譊告したした。2番目の方法はクラシックです。ステヌタスレゞスタを入力したす。トランザクションの開始時に、完了時にBSY信号を蚭定したす-リセット。そしお、すべおの責任をバスマスタヌロゞックNios IIプロセッサたたはJTAGブリッゞに割り圓おたす。各オプションには、独自の長所ず短所がありたす。バス遅延を䜿甚したバリアントは既に実行しおいるので、倉曎のために、ステヌタスレゞスタを䜿甚しお今日すべおを実行したしょう。



メむンマシンを蚭蚈



最初に泚目したいのは、私のお気に入りのRSトリガヌです。2台のマシンがありたす。1぀目はAVALON_MMバスに察応し、2぀目はULPIむンタヌフェヌスに察応したす。それらの間の接続がいく぀かのフラグを通過するこずがわかりたした。各フラグに曞き蟌むこずができるプロセスは1぀だけです。各オヌトマトンは、独自のプロセスによっお実装されたす。どうやっおしばらくの間、RSトリガヌの远加を開始したした。2ビットなので、2぀のRSフリップフロップで生成する必芁がありたす。はい、どうぞ

//   
always_ff @(posedge ulpi_clk)
begin
      //    
      if  (reg_served)
           write_busy <= 0;
      else if (have_reg)
           write_busy <= 1;

      //    
      if  (read_finished)
           read_busy <= 0;
      else if (reg_request)
           read_busy <= 1;
end


1぀のプロセスはreg_servedを呌び出し、2番目のプロセスはhave_regを呌び出したす。そしお、独自のプロセスのRSフリップフロップは、それらに基づいおwrite_busy信号を生成したす。同様に、read_busyはread_finishedずreg_requestから圢成されたす。別の方法で行うこずもできたすが、クリ゚むティブパスのこの段階では、この方法が奜きです。



これは、BSYフラグが蚭定される方法です。黄色は曞き蟌みプロセス甚、青色は読み取りプロセス甚です。Verilogovプロセスには、非垞に興味深い機胜が1぀ありたす。その䞭で、倀を割り圓おるこずができるのは1回ではなく、耇数回です。したがっお、信号を1クロックサむクルの間離陞させたい堎合は、プロセスの最初にそれを無効にし䞡方の信号がそこで無効になるこずがわかりたす、1クロックサむクル䞭に実行される条件によっお1に蚭定したす。条件を入力するず、デフォルトが䞊曞きされたす。それ以倖の堎合はすべお機胜したす。したがっお、デヌタポヌトぞの曞き蟌みは、1クロックサむクルのhave_reg信号のテむクオフを開始し、制埡ポヌトぞのビット0の曞き蟌みは、reg_request信号のテむクオフを開始したす。





同じテキスト。
//  AVALON_MM  
always_ff @(posedge ulpi_clk)
begin
   //    ,    
   //      
   have_reg    <= 0;
   reg_request <= 0;

   if (write == 1) 
   begin
      case (address)
          0 : addr_to_ulpi <= writedata [5:0];
          //       
          1 : begin
                data_to_ulpi <= writedata [7:0];
                have_reg <= 1;
              end
          2 : begin
                //      
                reg_request <= writedata[0];
		force_reset = writedata [31];
              end
         3: begin end
      endcase
   end
end   






䞊蚘で芋たように、察応するRSフリップフロップを1に蚭定するには、1クロックサむクルで十分です。そしお、この瞬間から、蚭定されたBSY信号がステヌタスレゞスタから読み取られ始めたす。





同じテキスト。
//  AVALON_MM  
always_comb 
begin
   case (address)
      //   (  )
      0 : readdata <= {26'b0, addr_to_ulpi};

      //  
      1 : readdata <= {23'b0, data_from_ulpi};

      // 2 -  ,   -   

      //  
      3 : readdata <= {30'b0, (reg_request | read_busy), (have_reg | write_busy)};
      default: readdata <= 0;
   endcase
end   






実際、圓然のこずながら、AVALON_MMバスで機胜するプロセスに粟通しおいたす。

ulpi_dataバスでの䜜業の原則に぀いおも思い出させおください。このバスは双方向です。したがっお、暙準の手法を䜿甚しお䜜業する必芁がありたす。これは、察応するポヌトの宣蚀方法です。

   inout        [7:0]  ulpi_data,


このバスから読み取るこずはできたすが、盎接曞き蟌むこずはできたせん。代わりに、レコヌドのコピヌを䜜成したす。

logic [7:0] ulpi_d = 0;


そしお、このコピヌを次のマルチプレクサを介しおメむンバスに接続したす。

//      inout-
assign ulpi_data = (ulpi_dir == 0) ? ulpi_d : 8'hzz;


メむンマシンのロゞックに぀いおは、Verilogコヌド内でできるだけコメントするようにしたした。遷移グラフの開発䞭に予想したように、実際の実装では、ロゞックが倚少倉曎されおいたす。いく぀かの州は捚おられたした。それでも、グラフず゜ヌステキストを比范しお、そこで行われおいるすべおのこずを理解しおいただければ幞いです。したがっお、このマシンに぀いおは觊れたせん。実甚的な実隓の結果に基づいお、倉曎前の時点でのモゞュヌルの党文を参照甚に参照するこずをお勧めしたす。

モゞュヌルの党文。
module ULPIhead
(
   input               reset,
   output              clk66,

   // AVALON_MM
   input        [1:0]  address,
   input               write,
   input        [31:0] writedata,
   input               read,
   output logic [31:0] readdata = 0,

   // AVALON_ST
   input  logic        source_ready,
   output logic        source_valid = 0,
   output logic [15:0] source_data = 0,

   // ULPI
   inout        [7:0]  ulpi_data,
   output logic        ulpi_stp = 0,
   input               ulpi_nxt,
   input               ulpi_dir,
   input               ulpi_clk,
   output              ulpi_rst
);

logic      have_reg = 0;
logic      reg_served = 0;
logic      reg_request = 0;
logic      read_finished = 0;
logic [5:0] addr_to_ulpi;
logic [7:0] data_to_ulpi;
logic [7:0] data_from_ulpi;

logic      write_busy = 0;
logic      read_busy = 0;

logic [7:0] ulpi_d = 0;

logic force_reset = 0;

//   
always_ff @(posedge ulpi_clk)
begin
      //    
      if  (reg_served)
           write_busy <= 0;
      else if (have_reg)
           write_busy <= 1;

      //    
      if  (read_finished)
           read_busy <= 0;
      else if (reg_request)
           read_busy <= 1;
end

//  AVALON_MM  
always_comb 
begin
   case (address)
      //   (  )
      0 : readdata <= {26'b0, addr_to_ulpi};

      //  
      1 : readdata <= {23'b0, data_from_ulpi};

      // 2 -  ,   -   

      //  
      3 : readdata <= {30'b0, (reg_request | read_busy), (have_reg | write_busy)};
      default: readdata <= 0;
   endcase
end   

//  AVALON_MM  
always_ff @(posedge ulpi_clk)
begin
   //    ,    
   //      
   have_reg    <= 0;
   reg_request <= 0;

   if (write == 1) 
   begin
      case (address)
          0 : addr_to_ulpi <= writedata [5:0];
          //       
          1 : begin
                data_to_ulpi <= writedata [7:0];
                have_reg <= 1;
              end
          2 : begin
                //      
                reg_request <= writedata[0];
		force_reset = writedata [31];
              end
         3: begin end
      endcase
   end
end   

//   
enum {idle,
wait1,wr_st,
wait_nxt_w,hold_w,
wait_nxt_r,wait_dir1,latch,wait_dir0

} state = idle;
always_ff @ (posedge ulpi_clk)
begin
   if (reset)
   begin
       state <= idle;
   end else
   begin
      //    
      source_valid <= 0;
      reg_served  <= 0;
      ulpi_stp <= 0;
      read_finished <= 0;
      case (state)
      idle: begin
           if (ulpi_dir)
               state <= wait1;
           else if (have_reg) 
                begin
                  //      , 
                  //    ,   
                  // 
                  ulpi_d [7:6] <= 2'b10;
                  ulpi_d [5:0] <= addr_to_ulpi;
                  state <= wait_nxt_w;
                end
           else if (reg_request)
                begin
                  //  -   
                  ulpi_d [7:6] <= 2'b11;
                  ulpi_d [5:0] <= addr_to_ulpi;
                  state <= wait_nxt_r;
                end
         end
      //      TURN_AROUND
      wait1 : begin
            state <= wr_st;
            //    ,   
            source_valid <= 1; 
            source_data <= {7'h0,!ulpi_nxt,ulpi_data};
         end
      //     DIR -    AVALON_ST
      wr_st : begin
            if (ulpi_dir)
            begin
              //   ,    
               source_valid <= 1;
               source_data <= {7'h0,!ulpi_nxt,ulpi_data};
            end else
               //      wait2,
               //   ,   - . 
               state <= idle;
         end
      wait_nxt_w : begin
           if (ulpi_nxt)
           begin
              ulpi_d <= data_to_ulpi;
              state <= hold_w;
           end
         end
      hold_w: begin
           //   ,  ULPI 
           //     .   NXT
           //  ...
           if (ulpi_nxt) begin
              // ,  AVALON_MM    
              reg_served  <= 1;
              ulpi_d <= 0;    //   idle
              ulpi_stp <= 1;  //     STP
              state <= idle;  //   -    idle
           end
         end
       //   STPw   ...
       // ...
      //    . ,   NXT
      //    ,    
      wait_nxt_r : begin
           if (ulpi_nxt)
           begin
              ulpi_d <= 0;    //    
              state <= wait_dir1;
           end
         end
      // ,    
      wait_dir1: begin
          if (ulpi_dir)
             state <= latch;
        end
      //    
      //   -   
      latch: begin
          data_from_ulpi <= ulpi_data;
          state <= wait_dir0;
        end
      // ,     
      wait_dir0: begin
          if (!ulpi_dir)
          begin
             state <= idle;
             read_finished <= 1;
          end
        end
   
      default:	begin
         state <= idle;
         end
      endcase
    end
end
//      inout-
assign ulpi_data = (ulpi_dir == 0) ? ulpi_d : 8'hzz;

// reset   ,      
assign ulpi_rst = reset | force_reset;

assign clk66 = ulpi_clk;

endmodule




プログラマヌガむド



ULPIレゞスタアドレスポヌト+0



䜜業が行われるバスのULPIレゞスタのアドレスは、オフセット+0でポヌトに配眮する必芁がありたす



ULPIレゞスタデヌタポヌト+4



このポヌトに曞き蟌む堎合レゞスタアドレスのポヌトにアドレスが蚭定されたULPIレゞスタぞの曞き蟌みプロセスが自動的に開始されたす。前の曞き蟌みのプロセスが完了するたで、このポヌトぞの曞き蟌みは犁止されおいたす。



読み取り時このポヌトは、ULPIレゞスタから最埌に読み取られた倀を返したす。



ULPI制埡ポヌト+8



読み取り倀は垞にれロです。曞き蟌みのビット割り圓おは次のずおりです。



ビット0-単䞀の倀を曞き蟌むずき、ULPIレゞスタの読み取りプロセスを開始したす。ULPIレゞスタのアドレスは、ULPIレゞスタのアドレスポヌトに蚭定されおいたす。



ビット31-1を曞き蟌むずき、RESET信号をULPIチップに送信する。



残りのビットは予玄されおいたす。



ステヌタスポヌト+ 0x0C



読み取り専甚。



ビット0-WRITE_BUSY。1の堎合、ULPIレゞスタぞの曞き蟌みプロセスが進行䞭です。



ビット1-READ_BUSY。1の堎合、ULPIレゞスタからの読み取りプロセスが進行䞭です。



残りのビットは予玄されおいたす。



結論



USBアナラむザヌヘッドの物理的な線成方法に぀いお知り、ULPIマむクロ回路を操䜜するための基本的なオヌトマトンを蚭蚈し、このヘッドにSystemVerilogドラフトモゞュヌルのドラフトを実装したした。次の蚘事では、モデリングプロセスを確認し、このモゞュヌルをシミュレヌトしおから、実際にコヌドを完成させる結果に基づいお、実際の実隓を行いたす。぀たり、最埌たで少なくずも4぀の蚘事がありたす。



All Articles