この記事は、 MIPSfpga-plusを他のボードに移植する方法に関する記事の続きであり、16 Digillent Pmod KYPDキーボードの例を使用して周辺機器をMIPSfpga-plusシステムに統合する方法について説明します。
キーボードをプロセッサに接続すると、ユーザーは彼と通信できます。 一般に、16個のボタンキーボードにはさまざまな表現がありますが、実装と動作原理は同じです。 したがって、この例によれば、同様のキーボードを統合できます。
ボードに組み込まれたADCの統合、およびNokia 5100からのディスプレイの接続については、チュートリアルの次の部分で説明します。
MIPSfpgaを他のボードに移植し、周辺機器をシステムに統合します。 パート3
また、MIPSfpgaの使用を開始する方法については、 記事に記載されています 。
MIPSは、最初の縮小コマンドセット(RISC)コンピューターアーキテクチャの1つです。 1981年のスタンフォード大学での研究の結果として登場し、コンピューターアーキテクチャの効率に革命をもたらしました。 MIPSアーキテクチャの商用利用は、1984年にMIPSfpga 2:Imagination Technologies v1.3によって開始されました。2016年3月1日、MIPS Computer Systemsは2013年にImagination Technologiesに買収されました。
MIPSプロセッサは、1980年と1990年に製造された高性能のシリコングラフィックワークステーションで使用されました。 最初に商業的に成功した製品は、5段コンベヤーを備えたMIPS R3000プロセッサーでした。 その後にR4000が続き、64ビット命令、スーパースカラーR8000、R10000命令の並外れた実行を備えたプロセッサ、および他の多くの高性能コアが追加されました。
時間が経つにつれて、MIPSアーキテクチャは、家庭用電化製品、ネットワーク機器、マイクロコントローラなどの低コスト、低電力製品のアプリケーション向けに進化してきました。 M4Kファミリは、5ステージパイプラインを備えた従来の32ビットアーキテクチャに基づいています。 一連の16ビットmicroMIPS命令がM14Kファミリに追加されました。これにより、コストが非常に重要な組み込みアプリケーションのプログラムのサイズが削減されます。 microAptivファミリでは、M14K命令セットが追加のデジタル信号処理命令で拡張されています。 M14Kコアには、マイクロコントローラー(UC)とマイクロプロセッサー(UP)の2つのバージョンがあります。 マイクロプロセッサバージョンにはキャッシュが含まれており、仮想メモリをサポートしています。これにより、LinuxやAndroidなどのオペレーティングシステムを実行できます。 M4Kアーキテクチャに基づいたMicrochip社の人気のあるPIC32マイクロコントローララインに精通しているかもしれません。
プロセッサは、メモリインターフェイスを使用して周辺機器と通信します。 つまり、これは、RAMメモリブロックからの場合と同じ方法で、接続された周辺機器からデータが書き込まれ、読み取られることを意味します。 プロセッサへの周辺機器の統合は、AHB-Liteバスに接続することにより行われます( 詳細なドキュメント )。 接続プロセスをより詳細に理解しようとします。
まず、信号がAHB-Liteバスをどのように通過するかを把握する必要があります。

周辺からのデータの読み取りプロセスはHRDATA信号を使用して実行され、データは書き込みイネーブル信号のアクティブHighレベルでHWRITEを使用して送信され、GPIOはHADDRのアドレスを選択することで選択されることがわかります。
1. Digilent Pmod KYPDキーボードの接続
最初に接続されたセンサーは、16ボタンのpmod KYPD( データシート )です。

私の場合、キーボードの接続にはPmodインターフェースが使用されましたが、ボード上の他のピンを使用できますが、* .xdc制限付きでファイルに登録する必要があります。 キーボードを接続するピンについては、次の表で説明します。
ピン配列とキーボード信号については、表で説明しています。
ピン | 信号 | 予定 | ピン | 信号 | 予定 |
---|---|---|---|---|---|
1 | Col4 | 4列 | 7 | Row4 | 4列 |
2 | Col3 | 3列 | 8 | Row3 | 3列 |
3 | Col2 | 2列 | 9 | Row2 | 2列 |
4 | Col1 | 1列 | 10 | Row1 | 1列 |
5 | GND | 接地接点 | 11 | GND | 接地接点 |
6 | GND | 電源接点 | 12 | Vcc | 電源接点 |
キーボード接続スキームは非常に簡単です。

キーボードをAHB-liteバスに統合するための次のステップは、Verilogでモジュールを作成することです。
キーボードは4つの行と列を使用して、16個の時計ボタンの配列を作成します。
この図は、R = 10kの抵抗によって行が電力に引き上げられていることを示しています。つまり、列の行を低論理レベルにアクティブ化することにより、特定の周波数のクロック信号が供給されます。 入力でのアクティブな信号が、行の出力でボタンが押されている列(列)と一致した瞬間に、低レベルが表示されます。 このようなプロセスを実装するには、デコーダーを作成する必要があります(モジュールの実装例もこの記事で説明されています )。

モジュール自体の形式は次のとおりです。
module kypd_decoder( input i_clk, input i_rst_n, input [3:0] i_row, output reg [3:0] o_col, output reg [3:0] o_number ); reg [19:0] counter; reg [3:0] col; reg [3:0] row; // row col parameter ZERO = 8'b11100111, ONE = 8'b01110111, TWO = 8'b01111011, THREE = 8'b01111101, FOUR = 8'b10110111, FIVE = 8'b10111011, SIX = 8'b10111101, SEVEN = 8'b11010111, EIGHT = 8'b11011011, NINE = 8'b11011101, A = 8'b01111110, B = 8'b10111110, C = 8'b11011110, D = 8'b11101110, E = 8'b11101101, F = 8'b11101011; always @(posedge i_clk or negedge i_rst_n) if (i_rst_n == 0) counter <= 20'b0; else counter <= counter + 1'b1; always @(posedge i_clk or negedge i_rst_n) if (i_rst_n == 1'b0) begin o_col <= 4'b1110; col <= 4'b1110; row <= 4'b1111; end else if (!counter) begin o_col <= {o_col [0], o_col [3:1]}; col <= o_col; row <= i_row; end always @(posedge i_clk or negedge i_rst_n) if (i_rst_n == 0) o_number <= 4'b0; else case ({row, col}) ZERO: o_number <= 4'h0; ONE: o_number <= 4'h1; TWO: o_number <= 4'h2; THREE: o_number <= 4'h3; FOUR: o_number <= 4'h4; FIVE: o_number <= 4'h5; SIX: o_number <= 4'h6; SEVEN: o_number <= 4'h7; EIGHT: o_number <= 4'h8; NINE: o_number <= 4'h9; A: o_number <= 4'hA; B: o_number <= 4'hB; C: o_number <= 4'hC; D: o_number <= 4'hD; E: o_number <= 4'hE; F: o_number <= 4'hF; endcase endmodule
Vivadoのモジュール図は次のようになります。

つまり、ソースの追加→デザインソースの追加または作成→次へ→ファイルの作成→(ファイル名の書き込み)→Ok→Ok→はいのように、Vivadoプロジェクトにデコーダモジュールを追加します。 空のVerilogファイルが作成されます。ファイルを作成した後、MIPSfpga-plusシステムの階層でそのファイルを見つけ、デコーダコードを記述して保存する必要があります。 モジュールをプロジェクトに追加する方法とVivadoを使用する方法の詳細については、以前の記事で説明しています。
MIPSfpgaを他のボードに移植し、周辺機器をシステムに統合します。 パート1
それでは、入力と出力をAHB-Liteバスとボードの物理出力に接続してみましょう。
mipsfpga_ahb階層は次のとおりです。

まず、Verilogヘッダーディレクトリmfp_ahb_lite_matrix_config.vhに、接続する周辺機器の名前を「define」ディレクティブを使用して記述します。 これを行うには、システムに光センサーを追加するための識別子を持つ行を見つけます(センサーの詳細については、前の記事で説明しています)。
行をコメント化する必要があります。これにより、光センサーをAHB-Liteバスに接続するためのコードに関連付けられているすべての行がオフになります。
//`define MFP_DEMO_LIGHT_SENSOR
周辺の行を書き、コメントを外します。
`define MFP_PMOD_KYPD
「mfp_system」を開き、光センサーのインスタンスの接続文字列を見つけます。
`ifdef MFP_DEMO_LIGHT_SENSOR
次に、デコーダモジュールのインスタンスを追加します。
`ifdef MFP_PMOD_KYPD kypd_decoder kypd_decoder ( .i_clk ( SI_ClkIn ), .i_rst_n ( KEY_0 ), .o_col ( KYPD_DATA [3:0] ), .i_row ( KYPD_DATA [7:4] ), .o_number ( KYPD_OUT ) ); `endif
デコーダーモジュールの信号は、バスインスタンスmfp_ahb_lite_matrix_with_loaderに接続する必要があります(必要な行を書き込むことができます。検索モジュールMFP_DEMO_LIGHT_SENSORを使用して光センサーを統合する例を参照してください)。
`ifdef MFP_PMOD_KYPD .KYPD_OUT ( KYPD_OUT ), `endif
デコーダーモジュールとバスのインスタンスを接続するには、ワイヤータイプの信号を追加します。
`ifdef MFP_PMOD_KYPD wire [3:0] KYPD_OUT; `endif
デコーダーモジュールをバスに接続した後、「mfp_system」モジュールの下の階層にある「mfp_ahb_lite_matrix_with_loader」に進み、入力/出力ポートを追加します。
`ifdef MFP_PMOD_KYPD input [3:0] KYPD_OUT, `endif
また、これらの信号を「mfp_ahb_lite_matrix」インスタンスに追加します。
`ifdef MFP_PMOD_KYPD .KYPD_OUT ( KYPD_OUT ), `endif
モジュール「mfp_ahb_lite_matrix_with_loader」の下の階層にある「mfp_ahb_lite_matrix」で同じアクションを実行し、入力/出力ポートを追加します。
`ifdef MFP_PMOD_KYPD input [3:0] KYPD_OUT, `endif
また、これらの信号をmfp_ahb_gpio_slaveインスタンスに追加します。
`ifdef MFP_PMOD_KYPD .KYPD_OUT ( KYPD_OUT ), `endif
「mfp_ahb_gpio_slave」モジュールに移動します。これはまさに引き裂かれたブロック(GPIO)なので、入力/出力ポートを追加します。
`ifdef MFP_PMOD_KYPD input [3:0] KYPD_OUT, `endif
ここで、モジュール「mfp_ahb_gpio_slave」を変更して、メモリマッピング(これからも定義します)でI / Oアドレスを検出し、検出したアドレスに対応するレジスタにデータ(HWDATA)を書き込む必要があります。
`ifdef MFP_PMOD_KYPD `MFP_PMOD_KYPD_IONUM : HRDATA <= { 28'b0, KYPD_OUT }; `endif
連絡先のアドレスを指定するには、ヘッダーファイル「mfp_ahb_lite_matrix_config.vh」を開いて以下を追加します。
`ifdef MFP_PMOD_KYPD `define MFP_PMOD_KYPD_ADDR 32'h1f800018 `endif
GPIOモジュールは、アドレスの最下位ビットを使用して、情報を読み書きする周辺機器を決定します。
`ifdef MFP_PMOD_KYPD `define MFP_PMOD_KYPD_IONUM 4'h6 `endif
階層を「mfp_system」モジュールに戻り、I / Oポートを追加しましょう。
`ifdef MFP_PMOD_KYPD inout [7:0] KYPD_DATA, input KEY_0, `endif
これらは、バスに接続したポートとまったく同じではないことに注意してください。 最上位のモジュールシェル(「cmoda7」がある)に移動して、「mfp_system」インスタンスに行を追加します。
`ifdef MFP_PMOD_KYPD .KYPD_DATA ( JA ), .KEY_0 ( ~ i_btn1 ), `endif
したがって、デコーダのモジュールをJA [7:0]出力に追加し、デコーダをAHB-Liteバスを介してプロセッサに接続しました。
この場合、シェルモジュールと制限ファイル(「cmoda7.xdc」があります)のJA I / Oポートは、すでに光センサーに使用されているため、追加する必要はありません。 しかし、他の場合には、そのようなアクションが必要になるので、理解のために、これらの行を単に示します。
module cmoda7 ( ... ... ... inout [ 7:0] JA );
cmoda7.xdc
## Pmod Header JA set_property -dict {PACKAGE_PIN G17 IOSTANDARD LVCMOS33} [get_ports {JA[0]}] set_property -dict {PACKAGE_PIN G19 IOSTANDARD LVCMOS33} [get_ports {JA[1]}] set_property -dict {PACKAGE_PIN N18 IOSTANDARD LVCMOS33} [get_ports {JA[2]}] set_property -dict {PACKAGE_PIN L18 IOSTANDARD LVCMOS33} [get_ports {JA[3]}] set_property -dict {PACKAGE_PIN H17 IOSTANDARD LVCMOS33} [get_ports {JA[4]}] set_property -dict {PACKAGE_PIN H19 IOSTANDARD LVCMOS33} [get_ports {JA[5]}] set_property -dict {PACKAGE_PIN J19 IOSTANDARD LVCMOS33} [get_ports {JA[6]}] set_property -dict {PACKAGE_PIN K18 IOSTANDARD LVCMOS33} [get_ports {JA[7]}]
「mfp_ahb_lite_matrix_config.vh」で思い出すと、次の行をコメントアウトしました。
//`define MFP_DEMO_LIGHT_SENSOR
これにより、システムを合成するときに、間に規定されたすべてのコード
`ifdef MFP_DEMO_LIGHT_SENSOR ... `endif
無視され、ポート使用の競合はありません。
キーボードのデコーダーが組み込まれた、作成されたMIPSfpga-plusシステムの図を見ることができます。このためには、RTL Analysys→Elaborated Designを開く→Schematicタブを開きます。 システム図全体がここに表示されます。接続されたデコーダモジュールの正確さを確認するには、RTLネットリストを調べてすべての連絡先を確認することをお勧めします。
これで、ビットストリームファイル(.bit)を生成し、FPGAに読み込むことができます。
キーボードとプロセッサの相互作用のための簡単なプログラムを作成します。
システムにコードをダウンロードするには、ダウンロードしたフォルダーmipsfpga plus→github→mipsfpga-plus→Programs→01_pmod_kypdを開き、「mfp_memory_mapped_registers.h」を開きます。
#define MFP_PMOD_KYPD_ADDR 0xBF800018 #define MFP_PMOD_KYPD (* (volatile unsigned *) MFP_PMOD_KYPD_ADDR )
次に、main.cを開いて、数行を記述してデモを行います。
#include "mfp_memory_mapped_registers.h" int main () { int n = 0; for (;;) { MFP_7_SEGMENT_HEX = MFP_PMOD_KYPD; } return 0; }
フォルダー内で、コードをコンパイルするスクリプトを見つけます。
02_compile_and_link
motorola_s_recordファイルを生成します。
08_generate_motorola_s_record_file
USB UARTコンバーターが接続されているCOMポートを確認します。
11_check_which_com_port_is_used
ファイル12_upload_to_the_board_using_uartを変更します。
set a=7 mode com%a% baud=115200 parity=n data=8 stop=1 to=off xon=off odsr=off octs=off dtr=off rts=off idsr=off type program.rec >\.\COM%a%
ここで、aはUSB UARTコンバーターが接続されているCOMポート番号です。 そして、プログラムをロードします。
12_upload_to_the_board_using_uart
結果:
次のパートでは、cmoda7の組み込みAPCとNokia 5100のLCDディスプレイをMIPSfpgaに追加する方法を説明します。
MIPSfpgaを他のボードに移植し、周辺機器をシステムに統合します。 パート3