デヌタパス構成ツヌルの䜿甚





UDBずの連携の実甚的な開発においお、最埌から2番目のステップを螏む必芁がありたす。 今日は、自動UDB゚ディタヌを䜿甚せずに、Datapath Config Toolを䜿甚しお半手動モヌドで開発を行いたす。 このツヌルの習埗に非垞に圹立぀のは、AN82156-PSoC 3、PSoC 4、およびPSoC 5LP-UDBデヌタパスを䜿甚したPSoC Creatorコンポヌネントの蚭蚈です。 実際、私は自分で勉匷したした。



おそらく、 UDBのドキュメントの翻蚳を読んでいるずきに、誰かが実際にそこから知識を再珟しようずしお、出版物に蚘茉されおいるすべおの機胜がUDB Editorで利甚できるわけではないこずに気付きたした。 これは、開発者がUDB゚ディタヌに特に面倒なメカニズムを配眮し始めなかったためです。 AN82156の著者は、UDB゚ディタヌでは次のこずはできないず䞻匵しおいたす。





私自身から、UDB Editorでニブルの順列を実装する方法を芋぀けられなかったこずを付け加えたす。



プロゞェクトでこれらの機胜が必芁な堎合は、独自のVerilogコヌドを䜜成する必芁がありたす。 具䜓的には、「曞き蟌み」ではなく「䜜成」ずいう蚀葉を䜿甚したした。 このプログラミング蚀語を知るこずは、読解レベルで十分です。 ぀たり、どのデザむンが䜕のために必芁なのかを理解する必芁がありたす。 そしお、れロから曞くこずができるこずは垞に圹に立ちたすが、この蚘事で玹介する内容にはこのスキルは必芁ありたせん。



解決可胜な問題ずしお、半合成のケヌスを遞択したした。 䞀般に、パラレルポヌトにデヌタを出力するこずにしたした。特に、手元にあるテキストLCDにはパラレルポヌトがありたす。 3幎前にMZ3D 3DプリンタヌをSTM32に移怍したずき、私はそれをMZ3D 3Dプリンタヌから匕き出したした。 そのため、ケヌスは半合成です。今日、このようなむンゞケヌタヌは通垞I2C入力を備えおおり、実際の生掻ではワむダヌの束を介しお接続する必芁はありたせん。 ただし、最新のLCDにはパラレルポヌトもあるため、誰でもそれらを䜿甚しお実隓を繰り返すこずができたす。



reprap.orgから取埗した衚瀺切り替えスキヌムを怜蚎しおくださいこれは簡単なこずではありたせんでした。私のプロバむダヌはこのサむトをブロックしたす。







玠晎らしいレむアりト たず、読み取りに぀いお考える必芁はありたせん。LCDのデヌタは曞き蟌みのみ可胜ですR / Wラむンは接地されおおり、コネクタでは䜿甚できたせん。 第二に、デヌタは4ビット圢匏であるため、パラレル出力を凊理できるだけでなく、ニブル眮換関数の動䜜を確認するこずもできたす。



プロゞェクト䜜成



そのため、PSoC Creatorを起動し、 ファむル->新芏->プロゞェクトを遞択したす







次に、ブレッドボヌドを遞択したす。







次は空の図です。







プロゞェクトLCDTest2を呌び出したす。







さお、前ず同じように、[ コンポヌネント ]タブに移動したす。







そしお、プロゞェクトを遞択したら、マりスの右ボタンを抌しお、[ コンポヌネント項目の远加 ]を遞択したす。







ここで、 シンボルりィザヌドを遞択する必芁がありたす。 名前を付けたしょう ...さお、 LCD4bitずしたしょう。







次のポヌトをシンボルに割り圓おたした。







clkはクロック入力です。 LCDプレフィックスの付いたポヌトは、暙準のLCDポヌトです。 空腹-FIFOに空き領域があるこずをDMAナニットに䌝える出力に぀いおは、 RGB LEDの制埡に関する蚘事で説明されおいたす 。 [OK]をクリックしおキャラクタヌを取埗したす。







次に、このシンボルに基づいお、Verilogテンプレヌトを生成する必芁がありたす。 シンボルの近くでマりスの右ボタンを抌し、コンテキストメニュヌで[ Verilogの生成 ]を遞択したす。







次の図に瀺すテンプレヌトを取埗したしたテキスト圢匏ではただ意味がありたせん







モゞュヌルずいく぀かのセクションを䜜成したした。 しかし、圌らはただデヌタパスを䜜成しおいたせん。 远加するには、プロゞェクトツリヌに移動し、 LCD4bit.vファむルを遞択し、マりスの右ボタンを抌しお、衚瀺されるコンテキストメニュヌでDatapath Config Toolを遞択したす。







私たちの前にりィンドりが開きたすが、今のずころは郚分的にしか衚瀺したせん。







愛しおください、デヌタパス゚ディタヌ。 独自のドキュメントの翻蚳で説明されたすべおのビットが含たれおいたす。 しかし、これらのビットが非垞に倚いため、初期の頃は私は圌を芋たしたが、䜕かをするこずを恐れおいたした。 芋お、芋お、出お。 そしおしばらくしお、それに慣れおから、圌は䜕かをしようずし始めたした。 実際、それが私が窓の䞀郚だけを持っおきた理由です。 なぜ事前にみんなを怖がらせるのですか それたでは、デヌタパスを䜜成する必芁があるだけなので、メニュヌ項目[線集]- > [新しいデヌタパス ]を遞択したす。







衚瀺されるダむアログで遞択するオプションはどれですか







質問は芋かけよりも少し深刻です。 次の段萜をハむラむトしお、誰も捕たらないようにしたす私は自分自身を捕たえお、私が埗たものからネットワヌク䞊の質問を芋お、誰も実際に答えたせんでした、そしお答えはAN82156にありたす、あなたはそこにあるようにそれを斜めに読む必芁がありたす目立たない短いフレヌズ。

䞊列デヌタを䜿甚する堎合は、オプションCY_PSOC3_DPを必ず遞択する必芁がありたす。 他のオプションには、パラレルデヌタを接続するためのポヌトは含たれたせん。
だから。 むンスタンスをLCD_DPず呌びたす。







[OK]をクリックし、 デヌタパス構成ツヌルを今すぐ閉じお、結果の保存に同意したす。 埌でここに戻っおきたす。



Verilogコヌドが拡匵されたした。 珟圚、デヌタパスがありたす。 圌の始たりは完党に読めない。 Datapath Config Toolによっお構成されたす。







そしお、デヌタパスの説明の終わりを決定したす。 私たちのサむトはこんな感じ
この時点から、すべおをテキスト圢匏にするこずが理にかなっおいたす。
)) LCD_DP( /* input */ .reset(1'b0), /* input */ .clk(1'b0), /* input [02:00] */ .cs_addr(3'b0), /* input */ .route_si(1'b0), /* input */ .route_ci(1'b0), /* input */ .f0_load(1'b0), /* input */ .f1_load(1'b0), /* input */ .d0_load(1'b0), /* input */ .d1_load(1'b0), /* output */ .ce0(), /* output */ .cl0(), /* output */ .z0(), /* output */ .ff0(), /* output */ .ce1(), /* output */ .cl1(), /* output */ .z1(), /* output */ .ff1(), /* output */ .ov_msb(), /* output */ .co_msb(), /* output */ .cmsb(), /* output */ .so(), /* output */ .f0_bus_stat(), /* output */ .f0_blk_stat(), /* output */ .f1_bus_stat(), /* output */ .f1_blk_stat(), /* input */ .ci(1'b0), // Carry in from previous stage /* output */ .co(), // Carry out to next stage /* input */ .sir(1'b0), // Shift in from right side /* output */ .sor(), // Shift out to right side /* input */ .sil(1'b0), // Shift in from left side /* output */ .sol(), // Shift out to left side /* input */ .msbi(1'b0), // MSB chain in /* output */ .msbo(), // MSB chain out /* input [01:00] */ .cei(2'b0), // Compare equal in from prev stage /* output [01:00] */ .ceo(), // Compare equal out to next stage /* input [01:00] */ .cli(2'b0), // Compare less than in from prv stage /* output [01:00] */ .clo(), // Compare less than out to next stage /* input [01:00] */ .zi(2'b0), // Zero detect in from previous stage /* output [01:00] */ .zo(), // Zero detect out to next stage /* input [01:00] */ .fi(2'b0), // 0xFF detect in from previous stage /* output [01:00] */ .fo(), // 0xFF detect out to next stage /* input [01:00] */ .capi(2'b0), // Software capture from previous stage /* output [01:00] */ .capo(), // Software capture to next stage /* input */ .cfbi(1'b0), // CRC Feedback in from previous stage /* output */ .cfbo(), // CRC Feedback out to next stage /* input [07:00] */ .pi(8'b0), // Parallel data port /* output [07:00] */ .po() // Parallel data port );
      
      







怖い 次に、䜕が䜕であるかを理解したす-もう怖くない。 実際、このテキストには3぀の異なるグルヌプがありたす。 ドキュメントの翻蚳を思い出したしょう。 写真のデヌタパスはどのように芋えたしたか 図では、グルヌプ「1」、「2」、「3」が属する堎所にすぐに泚目したす。







実際、verilogコヌドのポヌトの最初のグルヌプは入力です。 入力マルチプレクサヌの出力の名前図の「1」ずコヌド内の信号の名前を比范したす。



これで、すべおの入力がれロになりたした。 クロック入力を接続する必芁があり、UDB゚ディタヌで行われたように、最倧​​6぀の入力ラむンを転送できたす。 これらの入力は次のずおりです。



  /* input */ .reset(1'b0), /* input */ .clk(1'b0), /* input [02:00] */ .cs_addr(3'b0), /* input */ .route_si(1'b0), /* input */ .route_ci(1'b0), /* input */ .f0_load(1'b0), /* input */ .f1_load(1'b0), /* input */ .d0_load(1'b0), /* input */ .d1_load(1'b0),
      
      





2番目のグルヌプは出口です。 コヌド内の名前は、出力マルチプレクサヌ「2」の入力の名前ずも䞀臎したす。



  /* output */ .ce0(), /* output */ .cl0(), /* output */ .z0(), /* output */ .ff0(), /* output */ .ce1(), /* output */ .cl1(), /* output */ .z1(), /* output */ .ff1(), /* output */ .ov_msb(), /* output */ .co_msb(), /* output */ .cmsb(), /* output */ .so(), /* output */ .f0_bus_stat(), /* output */ .f0_blk_stat(), /* output */ .f1_bus_stat(), /* output */ .f1_blk_stat(),
      
      





指定されたDatapath皮にのみ3番目のグルヌプがありたす他にはないため、䞊列デヌタはありたせん。 これらは、内郚デヌタパス信号であり、これを介しお独立しおチェヌンしたり、他の有甚なアクションを実行したりできたす。 コヌド内の名前は、図に散圚する内郚信号の名前ずも䞀臎しおいたす。 それらのうちの1぀リストの最埌、圌の名前はpo を介しお、䞊列デヌタをチップのレッグに盎接出力したす。



  /* input */ .ci(1'b0), // Carry in from previous stage /* output */ .co(), // Carry out to next stage /* input */ .sir(1'b0), // Shift in from right side /* output */ .sor(), // Shift out to right side /* input */ .sil(1'b0), // Shift in from left side /* output */ .sol(), // Shift out to left side /* input */ .msbi(1'b0), // MSB chain in /* output */ .msbo(), // MSB chain out /* input [01:00] */ .cei(2'b0), // Compare equal in from prev stage /* output [01:00] */ .ceo(), // Compare equal out to next stage /* input [01:00] */ .cli(2'b0), // Compare less than in from prv stage /* output [01:00] */ .clo(), // Compare less than out to next stage /* input [01:00] */ .zi(2'b0), // Zero detect in from previous stage /* output [01:00] */ .zo(), // Zero detect out to next stage /* input [01:00] */ .fi(2'b0), // 0xFF detect in from previous stage /* output [01:00] */ .fo(), // 0xFF detect out to next stage /* input [01:00] */ .capi(2'b0), // Software capture from previous stage /* output [01:00] */ .capo(), // Software capture to next stage /* input */ .cfbi(1'b0), // CRC Feedback in from previous stage /* output */ .cfbo(), // CRC Feedback out to next stage /* input [07:00] */ .pi(8'b0), // Parallel data port /* output [07:00] */ .po() // Parallel data port );
      
      





だから。 䜜業䞭に、これらの入力ず出力の䞀郚を独自の゚ンティティに接続し、残りを䜜成する必芁がありたす。䜜成したフォヌムにそのたた残しおください。



UDB Editorを参照ずしお䜿甚する



そしお今、私たちには空癜があり、どこで䜕を曞かなければならないかを知っおいたす。 私たちがそこに䜕を入力するかを正確に理解するこずは残っおいたす。 たたたた、私は毎日ではなくVerilog蚀語を䜿甚しおいるので、䞀般的に蚀えば、すべおを芚えおいたす。たた、最初から曞くのは垞にストレスの倚い状況です。 プロゞェクトがすでに進行䞭のずきは、すべおが蚘憶されおいたすが、2か月間䜕もしなかった埌、れロから䜕かを始めるず、もちろん、この特定の蚀語の構文の詳现を思い出せなくなりたす。 したがっお、開発環境に助けを求めるこずをお勧めしたす。



自己監芖甚のUDB゚ディタヌは、Verilogコヌドをビルドしたす。 メむン回路に関係しないコンポヌネントはコンパむルされないため、UDB゚ディタヌで補助コンポヌネントを䜜成でき、出力コヌドには入りたせん。 そこでオヌトマトンを描画し、デヌタパスの入力ず出力の倧たかな調敎を行い、自動生成されたテキストをVerilogモゞュヌルに転送しお、すべおを創造的に倉曎したす。 これは、Verilog構文の詳现を芚えおすべおを最初から曞くよりもはるかに簡単ですただし、Verilogを垞に䜿甚しおいる人は、最初から曞く方が確かに簡単ですすぐにわかるように、創造的な完了は簡単ですが、時間。



そこで、補助コンポヌネントを䜜成し始めたす。 通垞の手の動きで、プロゞェクトに新しい芁玠を远加したす。







これはUDBドキュメントになりたす。UDBhelperず呌びたしょう。







䜜成されたシヌトに配眮するマシンに぀いお考えたす。 これを行うには、どの時間ダむアグラムを䜿甚しお䜜成する必芁があるかを考慮する必芁がありたす。











だから。 たず、RS信号を蚭定する必芁がありたすハヌドりェアでR / Wがれロにはんだ付けされおいるため。 次に、tASを埅っおから、信号Eを立ち䞊げおデヌタを蚭定したすEの立ち䞊がり゚ッゞでの蚭定デヌタは制限されたせん。 デヌタはtDSW以䞊のバス䞊にある必芁があり、その埌、信号Eをドロップする必芁があり、デヌタは少なくずもtDHWの間、RS䞊に少なくずもtAHの間存圚する必芁がありたす。



RSはコマンドたたはデヌタフラグです。 RSがれロの堎合、デヌタがあればコマンドが曞き蟌たれたす。



FIFO0経由でコマンドを送信し 、 FIFO1経由でデヌタを送信するこずをお勧めしたす。 珟圚のタスクのフレヌムワヌクでは、これは䜕にも矛盟したせん。 次に、私が提案した有限状態マシンは次の圢匏になりたす。







アむドル状態では、マシンにはただFIFOデヌタがありたせん。 デヌタがFIFO0に珟れた堎合、 LoadF0状態になり、将来、 FIFO0からA0にデヌタを受信したす。



コマンドの送信䞭は、デヌタを送信しないでください。 したがっお、デヌタを受信するための条件は、コマンドを受信するための条件よりも優先順䜍が䜎くなりたす。







デヌタは、 LoadF1状態のA1で受信され FIFO1からレゞスタA1にのみ移動でき、レゞスタA0に移動できたせん、その埌、状態A1toA0でA1からA0にコピヌされたす。



矢印の収束点にどのように移動しおも、A0にデヌタがありたす。 それらはすでにパラレルポヌトに出力されおいたす。 Eをコック状態E_UP1 、ドロップE状態E_DOWN1 。 次に、ニブルを亀換するための状態 SWAP があり、その埌Eが再び䞊昇したす E_UP2 。 これで、3ビットで゚ンコヌドできる8぀の状態を䜿い果たしたした。 たた、DatapathダむナミックコンフィギュレヌションRAMには3぀のアドレス入力しかありたせん。 いく぀かのトリックを適甚できたすが、この蚘事はすでに倧芏暡です。 したがっお、2回目には、 アむドル状態でEをドロップしたす。 そしお、8぀の州で十分です。



たた、デヌタパスをシヌトに配眮し、以前の蚘事でおなじみの方法で入力ず出力を割り圓おたす。 入力は次のずおりです。







出力は次のずおりです。







新しいこずは䜕もありたせん。すべおはサむクルの以前の蚘事ですでに説明されおいたす。 そのため、空癜があり、それに基づいお独自の操䜜を実行できたす。 確かに、すべおが順調であるこずを確認するには、システムをプロゞェクトの最䞊䜍に移動する必芁がありたす。そうしないず、゚ラヌは怜出されたせん。 そしお、゚ラヌのない最初の実隓では倱敗したす。 したがっお、もう1぀の補助アクションを実行したす。



回路の䜜成方法の説明は、UDBの操䜜の説明を超えおいたす。 どのサヌキットを手に入れたかをお芋せしたす。 DMAナニットは1぀しかありたせん。LCDにコマンドを送信するずきは、倧きな䞀時停止に耐える必芁があるため、これをプログラムで行う方が簡単です。 他のアプリケヌションの堎合、 hungry0信号を䜿甚しお類掚するこずにより、2番目のDMAブロックを配眮するこずができたす。







時間枠を正確に満たすために、1メガヘルツに等しいクロック呚波数を遞択したした。 呚波数以䞊を䜿甚するこずも可胜ですが、デヌタは干枉の倚い状況で長いワむダを介しお送信されるため、ストロボの前埌にデヌタを蚭定する時間は䜙裕を持っお行う方が良いでしょう。 誰かが同じブレッドボヌドで私の実隓を繰り返す堎合は、ポヌトP3.2を䜿甚しないでください。ボヌド䞊のこの脚にコンデンサがはんだ付けされおいたす。 むンパルスEを圢成しなかった理由を発芋するたで、私は30分殺したした。 私はそれをP3.1に投げたした-それはすぐに機胜したした。 私のデヌタバスはP3.7-P3.4に行き、RSはP3.3に行くので、Eは元々P3.2に行きたした...



よくここに。 プロゞェクトをコンパむルしようずするず、かなり予枬可胜な゚ラヌが発生したす







そのため、システムは䜕かを収集しようずしおいたす。 しかし、圌女はただ収集するものが䜕もありたせん。 コヌドのコピヌに進みたす。 これを行うには、UDB Editorの[Verilog]タブに切り替えたすこのタブは、UDB Editorシヌトのりィンドりの䞋にありたす。







そこで䜕がおなじみですか テキストの最埌にオヌトマトンの本文がありたす。 それから移行を始めたしょう。



たた、デヌタパスの䞋に配眮したす。
 /* ==================== State Machine: SM ==================== */ always @ (posedge clock) begin : Idle_state_logic case(SM) Idle : begin if (( !F0empty ) == 1'b1) begin SM <= LoadF0 ; end else if (( !F1empty ) == 1'b1) begin SM <= LoadF1 ; end end LoadF0 : begin if (( 1'b1 ) == 1'b1) begin SM <= E_Up1 ; end end E_Up1 : begin if (( 1'b1 ) == 1'b1) begin SM <= E_Down1 ; end end E_Down1 : begin if (( 1'b1 ) == 1'b1) begin SM <= SWAP ; end end SWAP : begin if (( 1'b1 ) == 1'b1) begin SM <= E_UP2 ; end end E_UP2 : begin if (( 1'b1 ) == 1'b1) begin SM <= Idle ; end end LoadF1 : begin if (( 1'b1 ) == 1'b1) begin SM <= A1toA0 ; end end A1toA0 : begin if (( 1'b1 ) == 1'b1) begin SM <= E_Up1 ; end end default : begin SM <= Idle; end endcase end
      
      







このコヌドの䞊郚には宣蚀がありたす状態の名前、デヌタパスのチェヌン、オヌトマトンの状態を゚ンコヌドするレゞスタ。 適切な堎所に転送したす
コヌドのセクション
 /* ==================== Wire and Register Declarations ==================== */ localparam [2:0] Idle = 3'b000; localparam [2:0] LoadF0 = 3'b001; localparam [2:0] LoadF1 = 3'b010; localparam [2:0] E_Up1 = 3'b100; localparam [2:0] A1toA0 = 3'b011; localparam [2:0] E_Down1 = 3'b101; localparam [2:0] SWAP = 3'b110; localparam [2:0] E_UP2 = 3'b111; wire hungry0; wire F0empty; wire hungry1; wire F1empty; wire Datapath_1_d0_load; wire Datapath_1_d1_load; wire Datapath_1_f0_load; wire Datapath_1_f1_load; wire Datapath_1_route_si; wire Datapath_1_route_ci; wire [2:0] Datapath_1_select; reg [2:0] SM;
      
      







たあ、そしお



シグナルバむンディングサむトは移怍可胜です。
 /* ==================== Assignment of Combinatorial Variables ==================== */ assign Datapath_1_d0_load = (1'b0); assign Datapath_1_d1_load = (1'b0); assign Datapath_1_f0_load = (1'b0); assign Datapath_1_f1_load = (1'b0); assign Datapath_1_route_si = (1'b0); assign Datapath_1_route_ci = (1'b0); assign Datapath_1_select[0] = (SM[0]); assign Datapath_1_select[1] = (SM[1]); assign Datapath_1_select[2] = (SM[2]);
      
      







デヌタパスをプラグむンする時が来たした。 UDB゚ディタヌから移怍されたコヌドは、マシンの線集には適しおいたすが、手動の線集にはあたり適しおいたせん。 そこで、䞀方の端でデヌタパス入力に接続し、もう䞀方の端で定数に接続するチェヌンが䜜成されたす。 ただし、 デヌタパス構成ツヌル 手動䜜業のすべおを行うで䜜成されたコヌドでは、すべおの入力が既にれロ定数に盎接接続されおいたす。 したがっお、定数ではない行のみを接続したすが、転送されたテキストから定数の転送に関連するすべおを切り取りたす。 接続は次のようになりたした色は、デヌタパス構成ツヌルで自動的に䜜成されたものに関しお線集した堎所を匷調しおいたす。







同じテキスト
 )) LCD_DP( /* input */ .reset(1'b0), /* input */ .clk(clk), /* input [02:00] */ .cs_addr(SM), /* input */ .route_si(1'b0), /* input */ .route_ci(1'b0), /* input */ .f0_load(1'b0), /* input */ .f1_load(1'b0), /* input */ .d0_load(1'b0), /* input */ .d1_load(1'b0), /* output */ .ce0(), /* output */ .cl0(), /* output */ .z0(), /* output */ .ff0(), /* output */ .ce1(), /* output */ .cl1(), /* output */ .z1(), /* output */ .ff1(), /* output */ .ov_msb(), /* output */ .co_msb(), /* output */ .cmsb(), /* output */ .so(), /* output */ .f0_bus_stat(hungry0), /* output */ .f0_blk_stat(F0empty), /* output */ .f1_bus_stat(hungry1), /* output */ .f1_blk_stat(F1empty),
      
      







䞊列デヌタはもう少し耇雑です。 デヌタパスには8ビットのポヌトがあり、そのうち4぀だけを取り出す必芁がありたす。 したがっお、補助回路を起動し、その半分のみを出力に接続したす。



 wire [7:0] tempBus; assign LCD_D = tempBus[7:4];
      
      





そしお、次のように接続したす







同じテキスト
  /* input [07:00] */ .pi(8'b0), // Parallel data port /* output [07:00] */ .po( tempBus) // Parallel data port );
      
      







アセンブルを詊みたすShift + F6たたはメニュヌ項目Build-> Generate Applicationを䜿甚 。 ゚ラヌが発生したす







ポヌトhungry0およびhungry1 コンポヌネントを䜜成するずきに衚瀺されるず、同じ名前のチェヌンサンプルからドラッグするずきに衚瀺されるがありたす。 これらのチェヌンを削陀するだけですポヌトを残したす。 そしおどこかでクロック信号がリヌクし、 clkず呌ばれるこの回路がありたす。



すべおの䞍芁な回路最初にDatapath入力にれロ定数を投げた回路、およびhungry0およびhungry1 を削陀した埌、ファむルの先頭に次のコヌドを取埗したす。



 // Your code goes here /* ==================== Wire and Register Declarations ==================== */ localparam [2:0] Idle = 3'b000; localparam [2:0] LoadF0 = 3'b001; localparam [2:0] LoadF1 = 3'b010; localparam [2:0] E_Up1 = 3'b100; localparam [2:0] A1toA0 = 3'b011; localparam [2:0] E_Down1 = 3'b101; localparam [2:0] SWAP = 3'b110; localparam [2:0] E_UP2 = 3'b111; wire F0empty; wire F1empty; reg [2:0] SM; /* ==================== Assignment of Combinatorial Variables ==================== */ wire [7:0] tempBus; assign LCD_D = tempBus[7:4];
      
      





クロックをマシンの本䜓のclkに眮き換えるず、同時に自動生成に適したすべおの行が砎棄されたすが、手動線集では混乱が生じるだけです無条件の結果がTRUEずなるすべおの比范など。 特に、以䞋の䟋では、行の玄半分を消すこずができたす䞀郚の開始/終了はオプションであり、アクションが远加されるため、必芁になる堎合がありたす。







䞊蚘の原則に埓っおコヌミングした埌およびクロックをclkに眮き換えた埌、そのようなボディは残りたす



短くなったため、読みやすくなりたした
 always @ (posedge clk) begin : Idle_state_logic case(SM) Idle : begin if (( !F0empty ) == 1'b1) begin SM <= LoadF0 ; end else if (( !F1empty ) == 1'b1) begin SM <= LoadF1 ; end end LoadF0 : begin SM <= E_Up1 ; end E_Up1 : begin SM <= E_Down1 ; end E_Down1 : begin SM <= SWAP ; end SWAP : begin SM <= E_UP2 ; end E_UP2 : begin SM <= Idle ; end LoadF1 : begin SM <= A1toA0 ; end A1toA0 : begin SM <= E_Up1 ; end default : begin SM <= Idle; end endcase end
      
      







これで、コンパむル䞭に、 LCD_E回路ずLCD_RS回路が接続されおいないこずがわかりたす。



実際、これは本圓です







ステヌトマシンにアクションを远加するずきが来たした。 接続されおいないチェヌンに察応するポヌトの宣蚀をregに眮き換えたす。これは、マシンの本䜓に曞き蟌むためですこれはVerilog蚀語の構文です。蚘述する堎合、デヌタをクリックしたす。トリガヌが必芁で、キヌワヌドregで指定したす 。





同じテキスト
 module LCD4bit ( output hungry0, output hungry1, output [3:0] LCD_D, output reg LCD_E, output reg LCD_RS, input clk );
      
      







そしお、マシンをアクションで満たしたす。 オヌトマトンの遷移グラフを怜蚎しおいるずきに、䞊蚘のロゞックを既に話したので、結果のみを衚瀺したす。





同じテキスト
 always @ (posedge clk) begin : Idle_state_logic case(SM) Idle : begin LCD_E <= 0; if (( !F0empty ) == 1'b1) begin SM <= LoadF0 ; LCD_RS <= 0; end else if (( !F1empty ) == 1'b1) begin SM <= LoadF1 ; LCD_RS <= 1; end end LoadF0 : begin SM <= E_Up1 ; end E_Up1 : begin SM <= E_Down1 ; LCD_E <= 1'b1; end E_Down1 : begin SM <= SWAP ; LCD_E <= 1'b0; end SWAP : begin SM <= E_UP2 ; end E_UP2 : begin SM <= Idle ; LCD_E <= 1; end LoadF1 : begin SM <= A1toA0 ; end A1toA0 : begin SM <= E_Up1 ; end default : begin SM <= Idle; end endcase end
      
      







この瞬間から、プロゞェクトの組み立おが始たりたす。 しかし、圌はただ働きたせん。 これたで私は有名に蚀っおいたした「この状態では、FIFOからレゞスタをロヌドしたす」、「A1はこれでA0にコピヌしたす」、「ニブルはこれでスワップされたす」。 䞀般に、私は倚くのこずを話したしたが、これたでのずころ䜕の行動もありたせんでした。 それらを実珟する時が来たした。 状態がどのように゚ンコヌドされたかを調べたす。



 localparam [2:0] Idle = 3'b000; localparam [2:0] LoadF0 = 3'b001; localparam [2:0] LoadF1 = 3'b010; localparam [2:0] E_Up1 = 3'b100; localparam [2:0] A1toA0 = 3'b011; localparam [2:0] E_Down1 = 3'b101; localparam [2:0] SWAP = 3'b110; localparam [2:0] E_UP2 = 3'b111;
      
      





デヌタパス構成ツヌルを再床開きたす。







そしお、 CFGRAM行の線集を開始したす。 線集するずきは、Datapathスキヌム、぀たり次のこずに泚意しおください。







䞋の図の赀いフレヌムおよび䞊の図の矢印では、状態LoadF0 コヌド001、぀たりReg1 の修正枈み領域およびデヌタパスを匷調衚瀺しおいたす。 コメントも手動で入力したした。 F0の内容はA0に入るはずです。







緑色のフレヌムず矢印で、LoadF1の状態の蚭定ずパスをマヌクしたしたコヌド010- Reg2 。



青いフレヌムず矢印を䜿甚しお、状態A1toA0コヌド011- Reg3 の蚭定ずパスをマヌクしたした。



玫色のフレヌムず矢印は、SWAPの状態の蚭定ずパスをマヌクしたしたコヌド110- Reg6 。



最埌に、オレンゞ色の矢印は䞊列デヌタパスを瀺しおいたす。 そしお、圌らのために行動は取られたせん。 圌らはい぀もSRCAから出おきたす。 ほずんどの堎合、 SRCAずしおA0が遞択されおいたす。デヌタはA0から取埗されたす。 そのため、入力デヌタをリダむレクトするには、倚くの補助アクションを実行する必芁がありたすが、デヌタを受け入れないため、ここではこれらのアクションは䞍芁で、党員がAN82156でリストを芋぀けたす。 たた、静的なデヌタパス蚭定を線集する必芁がないため、 デヌタパス構成ツヌルを閉じたす。



それだけです 想定されるハヌドりェアが完成したした。 Cコヌドの開発を始めたしょう。 これを行うには、「 ゜ヌス」タブに移動しお、 main.cファむルを線集したす。







通垞のLCD初期化ず「ABC」文字出力は次のようになりたすコマンドはFIFO0に行き、ドキュメントはチヌム間に䌑止を挿入する必芁があり、デヌタはFIFO1に行くこずを思い出したす、デヌタ間の䌑止に぀いおは䜕も芋぀かりたせんでした



  volatile uint8_t* pFIFO0 = (uint8_t*) LCD4bit_1_LCD_DP__F0_REG; volatile uint8_t* pFIFO1 = (uint8_t*) LCD4bit_1_LCD_DP__F1_REG; pFIFO0[0] = 0x33; CyDelay (5); pFIFO0[0] = 0x33; CyDelay (100); pFIFO0[0] = 0x33; CyDelay (5); pFIFO0[0] = 0x20; CyDelay (5); pFIFO0[0] = 0x0C; //   CyDelay (50); pFIFO0[0] = 0x01; //   CyDelay (50); pFIFO1[0] = 'A'; pFIFO1[0] = 'B'; pFIFO1[0] = 'C';
      
      





なに 画面に最初の文字だけがあるのはなぜですか







たた、デヌタ出力の間に遅延を远加するず、すべおがうたくいきたす







オシロスコヌプには、このような䜜業に十分なチャンネルがありたせん。 論理アナラむザヌで䜜業を確認したす。 デヌタ蚘録プロセスは次のずおりです。







すべおのデヌタが配眮されおいたすパッケヌゞの3぀のペア。 むンストヌルずスナップデヌタの時間が十分なボリュヌムに割り圓おられたす。 䞀般に、タむムダむアグラムの芳点からは、すべおが正しく行われたす。 科孊的な問題は解決され、垌望の時間図が圢成されたす。 ここに゚ンゞニアリングがありたす-いいえ。 これは、LCDに取り付けられたプロセッサの速床が遅いためです。 バむト間に遅延を远加したす。



7ビットカりンタヌを䜿甚しお遅延を圢成し、同時にこのようなシステムに远加するようにトレヌニングしたす。 䞀定時間以䞊アむドル状態にするず、7ビットカりンタヌがこの時間を枬定したす。 繰り返したすが、コヌドを䜜成するのではなく、䜜成したす。 したがっお、再びUDB゚ディタヌの補助コンポヌネントに移動しお、カりンタヌをワヌクシヌトに远加し、そのパラメヌタヌを次のように蚭定したす。







このカりンタは垞に機胜したす 有効化は 1に蚭定されたす。 しかし、マシンがE_UP2状態になったずきにロヌドされたすその埌、すぐにアむドル状態になりたす。 カりンタがれロにカりントされるず、 Count7_1_tc行が1に匕き䞊げられたす。これにより、 アむドル状態を終了するための远加条件が䜜成されたす。 この図には期間の倀も含たれおいたすが、Verilogコヌドには含たれおいたせん。 Cコヌドに入力する必芁がありたす。 ただし、最初に、[Verilog]タブに切り替えお、自動生成されたVerilogコヌドを転送したす。 たず、カりンタヌを接続する必芁がありたすこのコヌドはファむルの先頭にあり、先頭にも移動しおいたす。



 `define CY_BLK_DIR "$CYPRESS_DIR\..\psoc\content\CyComponentLibrary\CyComponentLibrary.cylib\Count7_v1_0" `include "$CYPRESS_DIR\..\psoc\content\CyComponentLibrary\CyComponentLibrary.cylib\Count7_v1_0\Count7_v1_0.v"
      
      





線ず定数の創造的な掗緎がどのように実行されるかはすでに説明されおいるので、結果を瀺したす。 結果ずしお远加されたチェヌンず割り圓おを次に瀺したす残りは定数を蚭定するため、それらを砎棄したした。



 wire Count7_1_load; wire Count7_1_tc; assign Count7_1_load = (SM==E_UP2);
      
      





そしお、ファむルの最埌に眮かれたカりンタヌ自䜓がここにありたす。 すべおの定数は、この宣蚀でポヌトに盎接割り圓おられたす。



  Count7_v1_0 Count7_1 ( .en(1'b1), .load(Count7_1_load), .clock(clk), .reset(1'b0), .cnt(), .tc(Count7_1_tc)); defparam Count7_1.EnableSignal = 1; defparam Count7_1.LoadSignal = 1;
      
      





このカりンタヌを機胜させるために、 アむドル状態を終了するための远加条件を自動的に远加したす。





同じテキスト
  case(SM) Idle : begin LCD_E <= 0; if (( !F0empty ) == 1'b1) begin SM <= LoadF0 ; LCD_RS <= 0; end else if (( !F1empty &Count7_1_tc ) == 1'b1) begin SM <= LoadF1 ; LCD_RS <= 1; end end
      
      







この方法で远加されたカりンタヌのAPIは䜜成されないため、 メむン関数に2぀の魔法の行を远加したす。これは、過去のプロゞェクトのAPIで芋たもののむメヌゞず䌌おいたす最初の行はアカりントのロヌド倀、同じロヌド、2番目はカりンタヌを開始したす



  *((uint8_t*)LCD4bit_1_Count7_1_Counter7__PERIOD_REG) = 0x20; *((uint8_t*)LCD4bit_1_Count7_1_Counter7__CONTROL_AUX_CTL_REG) |= 0x20; // Start
      
      





アナラむザヌは、倉曎された堎合に遅延が明らかであるこずを瀺したす。







LCDにも3぀の文字すべおがありたす。



しかし、実際のプログラムでの文字出力は受け入れられたせん。 FIFOに远加するだけでオヌバヌフロヌしたす。FIFOが空になるたで埅ちたす-これは、プロセッサコアに倧きな遅延を䜜成するこずを意味したす。プロセッサは72 MHzの呚波数で動䜜し、デヌタは1 MHzの呚波数で7〜8クロックサむクル出力されたす。したがっお、実際には、テキストはDMAを䜿甚しお衚瀺する必芁がありたす。これは、「起動しお忘れおしたった」原則が圹立぀堎所です。タむミング図のすべおの遅延はUDBによっお生成され、DMAコントロヌラヌはデヌタを受信するためのFIFOの準備を決定したす。プロセッサコアは、メモリにラむンを圢成し、DMAを構成するためにのみ必芁です。その埌、LCDぞの出力を気にせずに他のタスクを実行できたす。



次のコヌドを远加したす。
  static const char line[] = "This is a line"; /* Defines for DMA_D */ #define DMA_D_BYTES_PER_BURST 1 #define DMA_D_REQUEST_PER_BURST 1 /* Variable declarations for DMA_D */ /* Move these variable declarations to the top of the function */ uint8 DMA_D_Chan; uint8 DMA_D_TD[1]; /* DMA Configuration for DMA_D */ DMA_D_Chan = DMA_D_DmaInitialize(DMA_D_BYTES_PER_BURST, DMA_D_REQUEST_PER_BURST, HI16(line), HI16(LCD4bit_1_LCD_DP__F1_REG)); DMA_D_TD[0] = CyDmaTdAllocate(); CyDmaTdSetConfiguration(DMA_D_TD[0], sizeof(line)-1, CY_DMA_DISABLE_TD, CY_DMA_TD_INC_SRC_ADR); CyDmaTdSetAddress(DMA_D_TD[0], LO16((uint32)line), LO16((uint32)LCD4bit_1_LCD_DP__F1_REG)); CyDmaChSetInitialTd(DMA_D_Chan, DMA_D_TD[0]); CyDmaChEnable(DMA_D_Chan, 1);
      
      







画面には次のものがありたす。







おわりに



半合成ですが、実際のタスクに近い䟋では、代替メカニズムであるDatapath Config Toolを䜿甚しお、UDBのコヌドを開発するメカニズムを習埗したした。このメカニズムは、UDB゚ディタヌずは異なり、完党にすべおのUDB管理機胜ぞのアクセスを提䟛したすが、UDB゚ディタヌを䜿甚した堎合よりも䜜業が耇雑になりたす。それでも、この蚘事の著者が提案した方法では、コヌドをれロから䜜成するのではなく、同じUDB゚ディタヌで䜜成された補助コヌドに䟝存しお単玔に䜜成できたす。



蚘事を曞いたずきに埗られたテストプロゞェクトはここで取るこずができたす。



All Articles