誰かがPythonのプログラムでテキストファイルを解析し、別の人がPearlの正規表現でスクリプトを記述します。Cプログラマーはバッファとポインターをたまにいじって、時にはYaccとLexを使用します。
裸の鉄でテキストを解析することは可能ですか? プログラムはまったくありませんか?
「そして、それはどうですか?」友人が私に尋ねました。「Arduinoの助けを借りて?」
「Arduinoの内部には完全にフォンノイマンプロセッサがあり、プログラムは機能しています」と答えました。
「あぁ、これ、マイクロコード?」と私の友人は推測して私を勝利の目で見た。
「いいえ、「マイクロコード」という用語は、1970年代にプロセッサの特定の組織に使用されましたが、その使用は無効になりました」と私は答えて追加しました、「本当、x86がエンコードされるIntelプロセッサにはまだマイクロオペレーションがありますが、これも
異なります。 いいえ、次の図のように、AND-OR-NOT論理要素とDトリガーで構成されるデバイスを使用してテキストを解析します。
-不可能! -私の友人を叫びました-そのようなデバイスでは、プロセッサは横のどこかに座って、ひそかにウィンクする必要があります!
「なぜこれが不可能なのか」と私は反論した。「チューリングマシンを知っていますか?」 テープ上のテキストを解析し、側面には知性やアルドゥイノウインクはありません。
「まあ、チューリングマシンです」と友人は言いました。「デーモンマクスウェルのような抽象化です。」
「抽象化なし。テキストを解析する作業スキームが表示されるようになりました」と私は言いましたが、「最初に、なぜそれが必要なのかを説明します。」
1.ソフトウェアなしのハードウェアでテキストを解析する必要があったのはなぜですか
昨年、
MIPSfpga に関する一連のセミナーに主催者の1人として参加し
ました 。 MIPSfpgaは、Verilogのソースコードにプロセッサコアを含むパッケージで、変更、新しい命令の追加、マルチプロセッサシステムの構築、ソフトウェアとハードウェアの変更などを同時に行うことができます。 MIPSfpgaシステムは、Verilogueシミュレータでシミュレートしたり
、FPGAボードに合成して実装
したり、工場で実際にチップを作りたい場合に使用できます。
MIPSfpgaを備えたFPGA / FPGAボードは2回プログラムする必要があります-最初にPCからハードウェア構成を入力し(各FPGAセルの論理機能とそれらの間の接続を決定)、次にソフトウェア(PCからも)(プロセッサコマンドのシーケンス)を合成ハードウェアのメモリに入力しますシステム(
MIPS microAptiv UPプロセッサコア、インターコネクト、2つのメモリブロック、I / Oブロックを含む)。
ハードウェアの充填に問題はありません-ザイリンクスISE / VivadoとアルテラQuartus IIの両方に、ユーザーの追加なしでシンプルなUSBケーブルを使用して、使用しているカードにハードウェア構成をアップロードできるソフトウェアが含まれています。 これらのボードには、
Digilent Basys 3および
Nexys 4 DDR 、
Terasic DE0-CVなどが含まれます。
ハードウェア構成とは異なり、標準のMIPSfpga Getting Startedパッケージのソフトウェアは、
OpenBCDと呼ばれるソフトウェアと組み合わせて
BusBlasterと呼ばれる追加のボードを使用して、EJTAGデバッグインターフェイスを介してアップロードされます。 残念ながら、BusBlasterとOpen OCDの組み合わせは非常に粗雑です-WindowsおよびLinuxの一部のバージョンではドライバーに問題がある場合があります。 さらに、BusBlasterはロシアで購入するのは簡単ではありません。 したがって、セミナーの前に、BusBlaster / OpenOCDなしでシステムのソフトウェア部分をMIPSfpgaにアップロードする方法を考えました。
2.どのファイルを解析してシステムメモリに注入する必要があるか
MIPSfpgaにアップロードする必要があるソフトウェアは、通常のGCCをコンパイルしてELFファイルにリンクする最も一般的なCまたはアセンブラープログラムです。 GNUパッケージには、
objcopyプログラムも含まれています。このプログラムは、ELFをテキスト形式(Intel HEX、Motorola Sレコード、Verilogハードウェア記述言語で認識される$ readmemh組み込みサブルーチンなど)を含むさまざまな形式に変換できます。 最初はIntel HEX形式を使用したかったのですが、使用したMIPSの
objcopyオプションの1つではサポートされていないことがわかりました。 2番目のオプションは、形式を使用することでした
Motorola S-recordと、すべてがうまく機能しました。 この形式のチートシートは次のとおりです。
3.何をどのように入力するか-エンジニアリングソリューション
3.1。 BusBlasterを介したソフトウェアのアップロードを回避する最も簡単な方法は、合成中に単純にMIPSfpgaシステムに配置することです。これは、Verilogハードウェア記述言語のコードが論理要素とトリガーのグラフに変わるプロセスです。 ザイリンクスISE / VivadoシンセサイザープログラムとアルテラQuartus II
は、合成中にVerilog $ readmemh言語構成を認識し、テキストファイルのデータで初期化されるメモリを作成します 。 残念ながら、ユーザーが頻繁にソフトウェアを再コンパイルする場合、そのようなソリューションは非常に実用的ではありません。毎回、ハードウェアの再合成も必要になるため、15〜30分かかります。
3.1.1。 オプション3.1:FPGAの部分的な再構成。 私もそれを勉強しませんでした。なぜなら、この場合も待つのに長い時間がかかり、ほんの数秒しか待たないからです。 さらに、FPGAのメーカーに依存しないものが必要でした。
3.2。 組み込みプログラマに最も直感的に期待される方法は、プログラムの一部を修正し、システムの合成中にシステムに配置し(ブートローダー)、プログラムの別の部分をシリアルポート経由でPCからダウンロードすることです。 ブートプログラムは、PCからダウンロードしたプログラムの転送を開始し、このプログラムをデータの形で受け取り、メモリに書き込む必要があります。 このような方法は、
Habrのメモ
「MIPSfpga:canon the canon」で@Frantonyによって説明され
ました
。3.2.1。 メソッド3.2。 2つのバリエーションがあります-ダウンロードしたプログラムを、Motorola S-recordのような形式のテキストファイルとして転送する方法と、ボード上のブートローダーでこのファイルを解析する方法、またはPC上のテキストファイルを解析して、バイナリ形式でボードにデータを転送する方法です。
3.3。 私が使用した方法-データの受信、解析、メモリからのデータの送信はすべて、FPGAに実装されたハードウェアで完全に実行されます。 この方法の利点は、ボード上のソフトウェアがハードウェアローダーの存在をまったく知らないことです。 ハードウェアローダーは、PCからのデータを認識すると、プロセッサをリセットするように設定し、メモリ内のすべてのデータを受信して配置し、プロセッサをリセットから削除します。その後、プロセッサはリセット例外ハンドラのコードの読み取りと実行を開始します。
3.3.1。 他のユーザーや開発者と問題を議論する過程で、MIPSfpgaは、メモリで動作するプロセッサと同時に(およびプロセッサがリセットされているときではなく)PCからメモリにデータを書き込むための本格的なDMAポートを作成するというアイデアも提案しましたが、複雑すぎて拒否されましたそして、ロシアでのセミナー中にMIPSfpgaを使用することになっていた種類のタスクにとっては、概して無意味です。
4. PCへの接続はどのようになっていますか?
シリアルポートは非常に古い発明です。
UART /
RS-232Cは1960年代後半に登場しました。 1980年代のすべてのPCには、ファイルとして書き込むことができるCOMポートがありました。 信じられませんが、MS-DOSを生き延び、今までWindowsに残っています。 はい、はい、PCから外部シリアルポートにファイルを転送するために、コマンドライン「type
file-name COM
port-number 」に書き込むことができ
ます 。
Linuxにも、そのような接続があります(Linuxに接続されたMIPSfpgaはまだ試していませんが、これについて私にメールを送ったイタリアの友人が試しました)。 COMポートに対応するファイルにデータをコピーするLinuxユーザーは、
ダイヤルアップグループのメンバーである必要があります。
stty -F / dev / ttyUSB0 raw 115200
cat srec program.rec> / dev / ttyUSB0
同時に、現代のPCには古代のRS-232Cポートを
インストールせず、代わりに
FTDIの FTD32RLチップに基づく
アダプターを使用してUSB経由で「仮想COMポート」を作成します(注意!このチップには
バグの多い偽物があります ) FPGAで動作するには、アダプターの3.3 / 5Vスイッチを3.3Vに設定する必要があります。そうしないと、理論的にはFPGAのピン/出力を損傷する可能性があります。
上の写真に示されているアダプターに加えて、PCおよびUARTをFPGAに接続する
ために、Win XP / VISTA / 7/8 / 8.1用のPL2303TA USB TTL RS232コンバーターシリアルケーブルモジュールと呼ばれるケーブルを使用できます。 このケーブルは、オスのGPIO出力を備えたTerasic DE0-Nanoなどの小型ボードに使用すると便利です。 AliExpressなどのサイトでは、
PL2303HXチップに基づく安価なケーブルも
販売されていますが、このチップにはWindows 8.xとの互換性の問題があったため、PL2303TAに基づくケーブルを使用することをお勧めします(UPD:MIPSfpgaの最新バージョン+変更しましたDE0-Nanoボードの結論を使用したため、この図を交換する必要があり、その接続は正しくありません):
5. PCから受信したデータをどこにアップロードする必要がありましたか?
ロードされたプログラムをPCから合成されたMIPSfpga +システムのメモリにロードするためのモジュールを挿入する前(MIPSfpgaのバージョンと名付けたように)、そのモジュール階層は次のようになりました。
各モジュールの内容:
6.システムにハードウェアローダーを挿入すると、システムの階層はどのように変わりましたか?
4つの新しいモジュール:
以下は、
mfp_ahb_lite_matrix_with_loaderモジュールの階層レベルの図です。verilでコードをコンパイルした後、完全な合成(最適化、FPGA固有の要素へのマッピング、配置、トレース)の前に取得します。
mfp_srec_parser_to_ahb_lite_bridgeと
mfp_ahb_lite_matrixの間の
マルチプレクサーに注意して
ください 。これは、マイクロプロセッサーコアからのトランザクションまたはハードウェアローダーからのトランザクションをメモリーおよび入出力サブシステムに向けます。
7.シリアルポート、UARTに関するいくつかの言葉
UARTのトピックは、
最近も含めてHabréで何度も議論されてきたので、詳細については触れません。 私のレシーバー実装では、
UARTプロトコルの最も単純なバージョンを使用し
ます 。制御信号なし、1つのスタートビット、パリティなし、固定ビットレート、固定クロック/クロック/クロック用です。
mfp_uart_receiverモジュールは、RX信号からデータを順番に受信し、準備ができたら8ビットバイトを並列に出力します。 このモジュールには、RX信号のネガティブエッジを待機するステートマシンが含まれているため(開始ビットが決定されます)、その後、カウンターを使用してクロックをカウントして決定する正しい時点でデータビットを読み取ります。 ビットあたりのクロックサイクル数は非常に多く、50,000,000 Hz / 115,200ボー= 434クロックサイクル(または25 MHzの場合は217クロックサイクル)であるため、データ受信は非常に信頼できます。 モジュールインターフェイスは次のとおりです。
完全なモジュールコードは
http://github.com/MIPSfpga/mipsfpga-plus/blob/master/mfp_uart_receiver.vです。
初期コンパイル後の
mfp_uart_receiverモジュール
図 :
8.そして最後に、約束されたもの:裸のハードウェア、プロセッサ、ソフトウェアなしのMotorola S-Recordテキストパーサー
mfp_srec_parserモジュールは、
mfp_uart_receiverモジュールからバイトを受信し、ステートマシンを使用して
Motorola Sレコード形式のテキストとして解析します。 解析中、トランザクションは、合成されたMIPSfpga +システムのメモリに対しても生成されます。 これらのトランザクションは、テキストで指定されたアドレスで解析されたテキストから指定されたバイトでメモリを満たします。 モジュールインターフェイス:
ステートマシンの状態と使用されるASCII文字の定数の識別子を決定します。
記号定数「0」、「1」、...「9」、「A」、「B」、...「F」を4ビットの数値0、1、2、... 9、10、11、... 15に変換するための組み合わせロジック
状態マシンの変数。 左側は現在のサイクル/サイクルで作成された新しい値、右側は前のサイクルで形成されたレジスタ/ Dトリガー/ Dフリップフロップに記録された値です。 Verilogovskyの「reg」から、シンセサイザーは常にハードウェアの意味でDトリガー/レジスターを作成するとは限りません。 キーワード「reg」は、「常に」ブロックで割り当てることができる一種の変数としてのみ理解される必要があります。
変数を定義した後の割り当ては、生成されたアドレス(以前にレジスタに書き込まれた)のモジュール出力への割り当てです。
ステートマシンロジックは、組み合わせ部分と順次部分で構成されます。 これらの概念に慣れていない場合は、無料の
Harris&Harrisチュートリアルでそれらを読むことができます。
組み合わせ部分では、次の状態の値を計算します。「状態」という言葉は、変数
reg_stateが変換されるDトリガーのグループだけでなく、一般的に回路内のすべてのDトリガー/ Dフリップフロップ/ハードウェアレジスタを意味します(この投稿の文脈における3つの用語はすべて交換可能です)。 「有限状態機械」および「データを備えた状態機械」であると言う純粋主義者がいますが、これらの学力とその悪魔を針の先に置いておきます。
これが組み合わせ部分の始まりです。 同期設計方法では望ましくないラッチ(Dラッチ)の外観を監視しないために、結合されたalways-blockの最初に、計算されたすべての変数にデフォルト値を割り当てます。
変更は、UARTレシーバから新しいレターを受信したときにのみ発生します( "if(char_ready)")。 有限状態マシンでは、最初に文字 'S'が現れるのを待ってから、レコードのタイプ(タイプ '3'に興味があります)および次のバイトを書き込むアドレスを解析します。
データの解析を開始すると同時に、モジュールからの出力にアドレス/データトランザクションを生成します。
クロックジェネレーターのプラス側で、以前に計算した値を、リセットを必要としないレジスタに書き込みます。
そして今、リセットを必要とするレジスタに書き込みを行っています-明確な状態からステートマシンを起動するか、モジュールの出力で制御信号を定義するレジスタのいずれかです:
in_progressシグナル(「進行中」)は、アドレスで最初のレコードが認識された時点でオンになり(タイプ
S3 )、モジュールがファイル内の最後のレコードを認識するとオフになります(タイプ
S7 )。 この信号は、ボード上の外部インジケータに出力できます
。mfp_ahb_lite_matrix_with_loaderのマルチプレクサにも使用され、マイクロプロセッサコアまたはハードウェアローダーがメモリに書き込むかどうかを決定します。 さらに、
in_progressはマイクロプロセッサコアをリセットするために使用され、ハードウェアローダーがメモリに書き込むときに「カットダウン」されます。 ソフトウェアがメモリに書き込まれると、マイクロプロセッサが起動し、命令の読み取りを開始します(固定物理アドレス1FC0_0000から)。
入力テキストのエラーを検出するためのロジック。 メインのステートマシンと並行して動作し、その状態を使用します。
チェックサムを計算し、S-Recordテキストのチェックサムと比較するためのロジック。 メインのステートマシンと並行して動作し、その状態を使用します。
エラー信号の生成。 ハードウェアパーサーは、エラーが発生した行をユーザーに通知します。
完全なモジュールコードは
http://github.com/MIPSfpga/mipsfpga-plus/blob/master/mfp_srec_parser.vです。9. AHB-Liteバスへの橋についてのひと言
mfp_srec_parser_to_ahb_lite_bridgeモジュールは、
mfp_srec_parserモジュールから取得したアドレス/データトランザクションを、
MIPSfpgaが使用するAHB-Liteバスのトランザクションに変換します。
モジュールはアドレスも編集します-ソフトウェアが使用する仮想アドレスをハードウェアが使用する物理アドレスに変換します。 MIPS microAptiv UPプロセッサーにはMMU TLBがあり、仮想アドレスから物理アドレスへの柔軟かつ複雑なマッピングを可能にしますが、私のMIPSfpgaの使用例では、変換は簡単で固定されています-アドレスの上位3ビットをゼロで消去します。 MIPSfpgaの仮想メモリ管理デバイスの操作に興味がある場合は、ロシア語の
「MIPSプロセッサのメモリ管理デバイス」のプレゼンテーションをご覧ください。
ブリッジコード
mfp_srec_parser_to_ahb_lite_bridge :
http://github.com/MIPSfpga/mipsfpga-plus/blob/master/mfp_srec_parser_to_ahb_lite_bridge.v初期コンパイル後の
mfp_srec_parser_to_ahb_lite_bridgeモジュール
図 :
最後に、チップ上のシステムのデバイスを接続するために使用されるAHB-Liteバス自体についてです。
以下は、イマジネーションテクノロジーズのドキュメントからの抜粋です。このドキュメントは
、次の手順に従ってダウンロードできます。
特に、アドレス転送に関連してデータ転送を1クロックサイクル遅らせる必要がある理由を確認できます。 AHB-Liteプロトコルでは、新しいトランザクションのアドレスが前のトランザクションからのデータと同時にバスに配置されます。
初期コンパイル後の
mfp_ahb_lite_matrixモジュール
スキーマ 。 このモジュールには、2つのメモリブロックと、汎用I / Oのソフトウェアへのメモリアクセスを表示するモジュール-GPIO(汎用IO)の3つのスレーブモジュールが含まれます。
10.そして今何? 継続、追加、提案
この投稿では、MIPSfpgaプロジェクトの1つの側面とその改良版MIPSfpga +のみを説明しました。これは、昨年末にロシアを旅行中にBus Blaster / Open OCDの問題に悩まされないようにしたものです。 MIPSfpgaでGDBベースのデバッガーを使用する場合は、引き続きBus BlasterまたはEJTAGをサポートする別のデバッグアダプターを使用する必要があります。
しかし、MIPSfpgaテーマははるかに大きくなっています。 結局のところ、パッケージには、サムスン、マイクロチップ、その他の企業の新製品で使用される産業用プロセッサが含まれています。読者の皆さんは、これらの企業のエンジニアが使用するコードと同じコードを使用してその構造を試すことができます。 異なるラインプッシュポリシーを使用してキャッシュモジュールを記述し、マルチコアシステムを開発し、異なる周辺機器をMIPSfpgaにねじ込むことができます。 MIPSfpgaでプロジェクトを作成することに興味があり、同時にFPGAボードの購入予算を確保するのが難しい地方の大学で働いている場合は、1枚のボードを無料で入手できますが、残りはほとんどありません-詳細は
「象の配布:FPGAボードMIPSfpgaによる教育プロジェクト 。
」また、Habréには、コプロセッサーをMIPSfpgaに固定する方法に関するメモが既にありました-https
: //habrahabr.ru/post/276205/を参照して
ください 。