MIPSfpgaは、教育用に設計されたイマジネーションMIPS32 microAptivマイクロプロセッサで、キャッシュメモリとメモリ管理ユニットを備えています。 Verilogプロセッサコードはユーザーが利用でき、FPGAボード上のプロセッサのシミュレーションと実装に使用できます。
この記事では、Digilent cmodA7の例を使用して、MIPSfpga-plusプロセッサを他のボードに移植する方法について説明します。

これまで、MIPSFPGAは、Basys 3、Nexys4 ddrなどを含むALTERAやXilinxなどの会社によって人気のあるボードに移植されています(完全なリストは
githubにあります )。 このようなボードは、FPGA開発者の間で最も人気があります。 このようなボードの価格はかなり低く、プログラムは約50ドルでEJTAGインターフェイスとBus Blasterアダプターを使用してMIPSfpgaコアにロードされます。 Bus Blasterアダプターは、高速USB 2.0ケーブルを介してコマンドを受信し、EJTAGシリアルプロトコルに変換します。これにより、プログラムをMIPSfpgaカーネルにロードし、そこで実行されるプログラムのデバッグを制御できます。 比較的高価なBus Blasterの問題は、MIPSfpgaシステムにいくつかの改善を導入することで解決しました。 MIPSfpga-plusと呼ばれるMIPSfpgaシステムの改良版には、次の新機能が含まれています。
-50ドルのBus Blasterの代わりに5ドルのFTDIで販売されているUSB-to-UARTコネクタを使用してソフトウェアをダウンロードする機能。
-クロック周波数をオンザフライで50または25 MHzから1 Hz(1秒間に1サイクル)に変更して、キャッシュミスやコンベヤのリダイレクトなど、プロセッサをリアルタイムで監視する機能。
-SPIプロトコルと光センサーを統合する例。
-32 KBのメモリではなく1 KBに収まるソフトウェア初期化の小さなシーケンス。外部メモリを使用せずにMIPSfpgaをより幅広いFPGAボードに転送できます。 UARTの実装については、記事
MIPSfpgaおよびUARTで説明しています。
MIPSfpga-plusを使用したザイリンクスVivado 2016.4(64ビット)でのプロジェクトの作成
さまざまな周辺機器をMIPSfpga +に追加する前に、FPGAでシステムをロードして実行する必要があります。 以下のリストにボードがある場合、この手順のいくつかの手順をスキップできます。
移植されたボードbasys3
de0
de0_cv
de0_nano
de1
de10_lite
de2_115nexys4
nexys4_ddr
MIPSfpga-plusはすでにこれらのボードに移植されており、ここからダウンロードできます。
github.com/MIPSfpga/mipsfpga-plus/tree/master/boards別のケースでは、リストされたFPGAとは異なるボードがあれば、プロセッサをそのボードに移植することは難しくありません。 このために、次の指示が書かれています。これは、cmodA7ボードの例として示されています。
1.最初に、MIPSFPGAシステムでパッケージを取得する必要があります。 これを行う方法の詳細な手順:
→
mipsfpga-download-instructionまた、MIPSfpga-plus拡張機能の現在のバージョンをダウンロードする必要があります。
→
Mipsfpga-plus2.ザイリンクスボードの場合、Vivadoソフトウェアが使用されます。現在のバージョンはここからダウンロードできます。
→
Vivadoをダウンロード3.次に、Vivadoで新しいプロジェクトを作成します。

作成したプロジェクトを保存する場所を選択します。

次をクリック:

RTLプロジェクトを選択して、[次へ]をクリックします。

元のMIPSfpgaのシステムファイルを追加します。


また、mipsfpga-plusからダウンロードしたアーカイブにあるMIPSfpga-plusもあります。

以前にプロジェクトで説明したuartモジュールを追加します。

IPおよび定数ファイルの作成はスキップします。後で作成します。


次に、チップを選択するか、ボードを追加する必要があります。
Digilent
cmod A7ボードは、
低価格とADCの可用性のために選択されました。 FPGA回路を選択するには、ボードのドキュメントを読む必要があります。cmodA7にはxc7a35tcpg236-1チップがあります。

もう1つの方法は、ボードのファイルをVivadoライブラリに追加することです。この方法の方が優れています。1つ目は、チップよりもボードの名前を覚える方が便利で、2つ目は、将来Vivadoでブロックデザイナーを使用したい場合に便利な作業用の追加ツールがあるためですボードインターフェイス、IPコアなど
GitHubでダウンロードできます。これらのファイルを〜\ Vivado \ 2015.1 \ data \ board \(Vivado 2015.1以降に関連)に保存する必要があります。


そこで、MIPSfpga-plusを使用してプロジェクトを作成しました。
Artix-7チップに基づいたDigilent CmodA7ボードの例に関する移植手順
要するに、cmodA7ボードにはArtix-7チップが搭載されており、20800 LUT、41600 FF、225 KBブロックメモリ、48ピン、2つのADC出力があり、USB-Uartコンバーター、Quad-SPIフラッシュ、 JTAG、2つのクロックボタン、および3つのRGB(
データシート )の5つのLED。
MIPSfpgaシステムをcmodA7ボードに転送するには:
手順1. MIPSfpgaのI / OとcmodA7ボードのI / O間の対応を確立するラッパーモジュールを作成します。
ステップ2. cmodA7ボードと一致するようにMIPSfpgaシステムのメモリ容量を減らします。
手順3.ボードのI / OとFPGAパッケージの結論との対応を確立する制約ファイルを追加します。
手順1.新しいcmoda7.vシェルファイルを追加する







システムの階層にcmoda7.vトップモジュールをインストールします。

プロセッサの周波数を下げるために使用できるスイッチがcmoda7ボード上にないため(この変更はMIPSfpga-plusに現れました)、このモジュールはシェルモジュールに含まれていませんでした。 BUS Blasterが接続されているEJTAG出力を除外することもできます。
まず、AHB_liteバス構成ヘッダーファイルを追加します。
`include "mfp_ahb_lite_matrix_config.vh"
Advanced High-performance Bus(AHB)は、多くのマイクロプロセッサシステム、特に組み込みシステムで使用されるオープンインターフェイスです。 AHBを使用すると、複数のデバイスを簡単に接続できます。 AHB-Liteは、1つのマスターを備えたAHBの簡易バージョンです。

この構成には、1つのマスターデバイス、MIPSfpgaプロセッサ、および3つのスレーブがあります。RAM0、RAM1、GPIOは、それぞれ2つのRAMブロックとボードのI / Oデバイスへのアクセスモジュールです。 GPIOブロックで作業し、周辺機器とやり取りするためのモジュールを作成します。
メインの入力/出力ポートを書きましょう:
module cmoda7 ( input i_clk, input i_btn0, input i_btn1, input RsRx, output [ 6:0] seg, output dp, output [ 3:0] an, output led0_r, output led0_g, output led0_b, inout [ 7:0] JA );
i_clk-周波数を持つボードのクロックジェネレーターの信号(cmodA7 12 MHzの場合)。
i_btn0-ボタンはプロセッサを再起動するために使用されます。
i_btn1-n / c。
RsRx-uart受信信号。
seg、dp、an、-7セグメント4ビットインジケーターを接続するための接点。
led_r、led_g、led_b、-ボードに置かれたRGB LEDの結論。
JA-Pmodインターフェース。
メイン信号はクロック信号で、残りは周辺機器を接続するためにリセット(i_btn0)します。

cmoda7.vモジュールの主な目標は、MIPSfpga-plusシステム(mipsfpga_sys)のインスタンスを作成し、それをボードのI / Oに接続することです。
wire clock; wire reset = i_btn0; wire display_clock; wire [7:0] anodes; wire [`MFP_N_BUTTONS - 1:0] IO_Buttons; wire [`MFP_7_SEGMENT_HEX_WIDTH - 1:0] IO_7_SegmentHEX; assign IO_Buttons = { { `MFP_N_BUTTONS - 2 { 1'b0 } } , i_btn0, i_btn1 }; mfp_system mfp_system ( .SI_ClkIn ( clock ), .SI_Reset ( reset ), .HADDR ( ), .HRDATA ( ), .HWDATA ( ), .HWRITE ( ), .EJ_TRST_N_probe ( ), .EJ_TDI ( ), .EJ_TDO ( ), .EJ_TMS ( ), .EJ_TCK ( ), .SI_ColdReset ( ), .EJ_DINT ( 1'b0 ), .IO_Switches ( ), .IO_Buttons ( IO_Buttons ), .IO_RedLEDs ( ), .IO_GreenLEDs ( ), .IO_7_SegmentHEX ( IO_7_SegmentHEX ), `ifdef MFP_DEMO_LIGHT_SENSOR .SPI_CS ( JA [0] ), .SPI_SCK ( JA [3] ), .SPI_SDO ( JA [2] ), `endif .UART_RX ( RsRx ), .UART_TX ( ) ); `ifdef MFP_DEMO_LIGHT_SENSOR assign JA [1] = 1'b0; `endif
移植されたシステムをテストするときは、MFP_DEMO_LIGHT_SENSORを使用します。 mfp_systemシステムの出力に見られるように、4ビット7セグメントインジケーターのデコーダーモジュールに出力する32ビットIO_7_SegmentHEXバスがあり、インスタンスモジュール「mfp_multi_digit_display」をシェルに接続します。
mfp_multi_digit_display multi_digit_display ( .clock ( display_clock ), .resetn ( ~ reset ), .number ( IO_7_SegmentHEX ), .seven_segments ( seg ), .dot ( dp ), .anodes ( an ) )
デコーダーを作成するとき、インジケーターが共通のアノードまたはカソードにあるかどうかを確認する必要があります。
共通アノードを備えた7セグメントインジケーターデコーダーのコードは次のとおりです。
module mfp_single_digit_seven_segment_display ( input [3:0] digit, output reg [6:0] seven_segments ); always @* case (digit) 'h0: seven_segments = 'b1000000; // abcdefg 'h1: seven_segments = 'b1111001; 'h2: seven_segments = 'b0100100; // --a-- 'h3: seven_segments = 'b0110000; // | | 'h4: seven_segments = 'b0011001; // fb 'h5: seven_segments = 'b0010010; // | | 'h6: seven_segments = 'b0000010; // --g-- 'h7: seven_segments = 'b1111000; // | | 'h8: seven_segments = 'b0000000; // ec 'h9: seven_segments = 'b0011000; // | | 'ha: seven_segments = 'b0001000; // --d-- 'hb: seven_segments = 'b0000011; 'hc: seven_segments = 'b1000110; 'hd: seven_segments = 'b0100001; 'he: seven_segments = 'b0000110; 'hf: seven_segments = 'b0001110; endcase endmodule //-------------------------------------------------------------------- module mfp_multi_digit_display ( input clock, input resetn, input [31:0] number, output reg [ 6:0] seven_segments, output reg dot, output reg [ 7:0] anodes ); function [6:0] bcd_to_seg (input [3:0] bcd); case (bcd) 'h0: bcd_to_seg = 'b1000000; // abcdefg 'h1: bcd_to_seg = 'b1111001; 'h2: bcd_to_seg = 'b0100100; // --a-- 'h3: bcd_to_seg = 'b0110000; // | | 'h4: bcd_to_seg = 'b0011001; // fb 'h5: bcd_to_seg = 'b0010010; // | | 'h6: bcd_to_seg = 'b0000010; // --g-- 'h7: bcd_to_seg = 'b1111000; // | | 'h8: bcd_to_seg = 'b0000000; // ec 'h9: bcd_to_seg = 'b0010000; // | | 'ha: bcd_to_seg = 'b0001000; // --d-- 'hb: bcd_to_seg = 'b0000011; 'hc: bcd_to_seg = 'b1000110; 'hd: bcd_to_seg = 'b0100001; 'he: bcd_to_seg = 'b0000110; 'hf: bcd_to_seg = 'b0001110; endcase endfunction reg [2:0] i; always @ (posedge clock or negedge resetn) begin if (! resetn) begin seven_segments <= bcd_to_seg (0); dot <= 0; anodes <= 8'b00000001; i <= 0; end else begin seven_segments <= bcd_to_seg (number [i * 4 +: 4]); dot <= 0; anodes <= (1 << i); i <= i + 1; end end endmodule
クロックの各立ち上がりエッジで確認できるように、対応する信号bcd_to_segはseven_segmentsで出力され、インジケータービット間の切り替えは、対応するアノード(またはカソード)のアクティブ信号を切り替えることによって行われます。
50 MHzの周波数の信号はプロセッサの入力に到達するため、後で作成しますが、そのような周波数でインジケーターの値を変更しても、目はこれらの変化に気づきません(7セグメントインジケーターの値の通常の表示には、約763 Hzの周波数が必要です) 。 これを行うには、分周器のインスタンスを接続します。
mfp_clock_divider_50_MHz_to_763_Hz mfp_clock_divider_50_MHz_to_763_Hz (clock, display_clock)
ソースファイルには、50 MHz〜763 Hzの分周器はありません。 したがって、mfp_clock_dividers.vファイルに追加します。

module mfp_clock_divider_50_MHz_to_763_Hz ( input clki, output clko ); mfp_clock_divider # (.DIV_POW_SLOWEST (16)) mfp_clock_divider ( .clki ( clki ), .sel_lo ( 1'b1 ), .sel_mid ( 1'b0 ), .clko ( clko ) ); endmodule
リセットおよびクロック、RsRx、IO_Buttons信号がシステムに入力されます。 しかし、最上位モジュールの入力では、信号はクロックではなくi_clkです。 実際には、ボードには12 MHzクロックがあり、FPGAのプロセッサは50 MHz以上の周波数で動作できます。異なるクロック周波数を持つ別のボードがある場合はどうでしょう(たとえば、Nexys 4 DDRのクロック周波数は100 MHzです)。 この問題は、Clocking Wizard(PLL)IPカーネルを作成することで解決されます;このためには、IPディレクトリを開きます。

Clocking Wizardを開きます。

ボードタブはそのままにするか、必要な入力を構成してクロックオプションタブに移動します。MMODAは、12 MHzのcmoda7でMMCMを選択するため、PLL 19〜800 MHzよりも広い範囲10〜800 MHzの入力周波数を選択できます。ただし、他のボードでは、他のパラメーターを選択できます。

[出力クロック]タブで、周波数を50 MHzに設定します(周波数を試してみてください。他のFPGAには他の特性がある場合があります)。

リセットとロックも解除します。

ポートの名前変更、MMCM設定、および概要をそのままにして、[OK]、[OK]の順にクリックし、次のウィンドウで[生成]を選択します。

最後のタッチは、RGB Ledの連続割り当てです。これは、フローティング状態の図からわかるように、それらが暗く点灯し、それらをオフにしたいためです。

assign led0_r = 1'b1; assign led0_g = 1'b1; assign led0_b = 1'b1;
最後に次のように書きます:
endmodule
シェルモジュールが作成されました。メモリのサイズ変更に移りましょう。
手順2. cmoda7ボードに合わせてMIPSfpgaシステムのメモリサイズを削減する
cmoda7ボードには、225 KBのブロックメモリがあります。 したがって、2つのメモリブロック(128 KバイトのRAMリセットと256 KバイトのRAMプログラム)はcmoda7ボードに収まりません。 ブートコードは32 KBに収まるため、64 KBのプログラムのニーズを制限できます。 したがって、必要なメモリの合計(32 Kバイト+ 64 Kバイト= 96 Kバイト)は、cmoda7ボードのメモリサイズに対応します。 残りの225-96 = 129 Kバイトのメモリは、キャッシュメモリなど、MIPSfpgaシステムの他のニーズに使用できます。
mfp_ahb_lite_matrix_config.vhシェルファイルに含めたVerilogヘッダーファイルで宣言されているメモリのサイズを変更することにより、メモリ量を削減できます。 mipsfpga_ahb_const.vhファイルを開きます。 リセットRAM(またはブートRAM)のアドレスは13ビットで構成されています。 したがって、リセットRAMの量は213 32ビットワード= 215バイト= 32 Kバイトです。

`define H_RAM_RESET_ADDR_WIDTH 13
プログラムのRAMアドレスは14ビットで構成されています。 したがって、プログラムRAMの量は214 32ビットワード= 216バイト= 64 Kバイトです。
`define H_RAM_ADDR_WIDTH 14
ステップ3. cmoda7制約ファイルを作成する
次に、シェルモジュールの外部信号とFPGA cmoda7ボードのピンの間の対応を設定する「cmoda7.xdc」を作成します(
cmoda7のピンの完全なリストを含むxdcファイル )。


たとえば、次の行は、i_clk入力と、cmoda7ボードから12 MHzクロック信号を受信するFPGA L17ハウジングの出力との間の対応を確立します。
set_property -dict {PACKAGE_PIN L17 IOSTANDARD LVCMOS33} [get_ports i_clk] create_clock -period 83.330 -name sys_clk_pin -waveform {0.000 41.660} -add [get_ports i_clk]
信号の次の出力時間制限も制限ファイルに追加する必要があります。
# I/O virtual clock create_clock -period 83.330 -name "clk_virt" # tsu/th constraints set_input_delay -clock "clk_virt" -min -add_delay 0.000 [get_ports i_btn0] set_input_delay -clock "clk_virt" -max -add_delay 10.000 [get_ports i_btn0] set_input_delay -clock "clk_virt" -min -add_delay 0.000 [get_ports i_btn1] set_input_delay -clock "clk_virt" -max -add_delay 10.000 [get_ports i_btn1] set_input_delay -clock "clk_virt" -min -add_delay 0.000 [get_ports led0_b] set_input_delay -clock "clk_virt" -max -add_delay 10.000 [get_ports led0_b] set_input_delay -clock "clk_virt" -min -add_delay 0.000 [get_ports led0_g] set_input_delay -clock "clk_virt" -max -add_delay 10.000 [get_ports led0_g] set_input_delay -clock "clk_virt" -min -add_delay 0.000 [get_ports led0_r] set_input_delay -clock "clk_virt" -max -add_delay 10.000 [get_ports led0_r] ## PMOD ALS set_output_delay -clock "clk_virt" -min -add_delay 0.000 [get_ports {JA[0]}] set_output_delay -clock "clk_virt" -max -add_delay 10.000 [get_ports {JA[0]}] set_output_delay -clock "clk_virt" -min -add_delay 0.000 [get_ports {JA[1]}] set_output_delay -clock "clk_virt" -max -add_delay 10.000 [get_ports {JA[1]}] set_input_delay -clock "clk_virt" -min -add_delay 0.000 [get_ports {JA[2]}] set_input_delay -clock "clk_virt" -max -add_delay 10.000 [get_ports {JA[2]}] set_output_delay -clock "clk_virt" -min -add_delay 0.000 [get_ports {JA[3]}] set_output_delay -clock "clk_virt" -max -add_delay 10.000 [get_ports {JA[3]}] set_input_delay -clock "clk_virt" -min -add_delay 0.000 [get_ports {seg[*]}] set_input_delay -clock "clk_virt" -max -add_delay 10.000 [get_ports {seg[*]}] set_input_delay -clock "clk_virt" -min -add_delay 0.000 [get_ports {an[*]}] set_input_delay -clock "clk_virt" -max -add_delay 10.000 [get_ports {an[*]}] set_input_delay -clock "clk_virt" -min -add_delay 0.000 [get_ports dp] set_input_delay -clock "clk_virt" -max -add_delay 10.000 [get_ports dp] set_output_delay -clock "clk_virt" -min -add_delay 0.000 [get_ports RsRx] set_output_delay -clock "clk_virt" -max -add_delay 10.000 [get_ports RsRx]
MIPSfpgaテスト
ボードに移植されたプロセッサをテストできます。そのためには、構成ファイル「mfp_ahb_lite_matrix_config.vh」に移動して、行のコメントを解除する必要があります。
`define MFP_DEMO_LIGHT_SENSOR

したがって、
Derilent PmodALS光センサーに接続するために、Veriogで作成されたSPIインターフェイスモジュールをAHB Liteバスに接続しました。
SPIモジュール module mfp_pmod_als_spi_receiver ( input clock, input reset_n, output cs, output sck, input sdo, output reg [15:0] value ); reg [21:0] cnt; reg [15:0] shift; always @ (posedge clock or negedge reset_n) begin if (! reset_n) cnt <= 22'b100; else cnt <= cnt + 22'b1; end assign sck = ~ cnt [3]; assign cs = cnt [8]; wire sample_bit = ( cs == 1'b0 && cnt [3:0] == 4'b1111 ); wire value_done = ( cnt [21:0] == 22'b0 ); always @ (posedge clock or negedge reset_n) begin if (! reset_n) begin shift <= 16'h0000; value <= 16'h0000; end else if (sample_bit) begin shift <= (shift << 1) | sdo; end else if (value_done) begin value <= shift; end end endmodule

接続図を図に示します。

センサーはPmodポートに接続され、その出力は「cmoda7.xdc」で説明されており、JA [7..0]として登録されています。
## Pmod Header JA set_property -dict {PACKAGE_PIN G17 IOSTANDARD LVCMOS33} [get_ports {JA[0]}] ... set_property -dict {PACKAGE_PIN K18 IOSTANDARD LVCMOS33} [get_ports {JA[7]}]
RTLスキームは、RTL Analisys→Schematicタブで確認できます。SPIインターフェイスモジュール「mfp_pmod_als_spi_receiver」は「mfp_system」にあります。

作成したプロジェクトをFPGAに読み込むには、ビットストリームファイル「cmoda7.bit」を生成する必要があります。そのためには、[プログラムとデバッグ]→[ビットストリームの生成]タブで、操作が完了するまで待ちます。

ビットストリームファイルを作成した後、ボードにダウンロードする必要があります。そのためには、[プログラムとデバッグ]タブで[ハードウェアマネージャーを開く]→[ターゲットを開く]→[自動接続]→[プログラムデバイス]を開き、システムをロードします:

センサーを操作するためのソフトウェアをダウンロードする
プロセッサがセンサーと通信するには、プログラムを作成し、それをRAM1ユニットに読み込む必要があります。RAM1ユニットは、AHB Liteバスにも接続されています。
MIPSfpgaプロセッサは、イマジネーションの
Codescape開発ツールを使用してプログラムされます。 Codescape SDKとOpenOCDをインストールします。 Codescapeは、C言語とアセンブリ言語の両方でのプログラミングをサポートしています。
システムにコードをダウンロードするには、ダウンロードしたフォルダーmipsfpga plus→github→mipsfpga-plus→Programs→01_light_sensorにアクセスして、「mfp_memory_mapped_registers.h」を開きます。
#define MFP_LIGHT_SENSOR_ADDR 0xBF800014 #define MFP_LIGHT_SENSOR (* (volatile unsigned *) MFP_LIGHT_SENSOR_ADDR )
次に、main.cを開き、数行を記述します。
#include "mfp_memory_mapped_registers.h" int main () { int n = 0; for (;;) { MFP_7_SEGMENT_HEX = MFP_LIGHT_SENSOR; } 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
システムの移植の結果はビデオで見ることができます:
プロセッサ、およびハードウェア記述言語(Verilog、VHDL)で新しいモジュールを作成する機能、回路、コンピュータアーキテクチャ、マイクロアーキテクチャ(プロセッサパイプラインの構成)、アセンブリ言語プログラミング、および学習の開始に役立つその他の機能を理解するためエレクトロニクスに関連するすべてのものについては、記事「
ロシアの電子工学、コンピュータアーキテクチャ、低レベルプログラミングに関する無料チュートリアル」に記載されている本を読むことをお勧めします。
次のパートでは、例として
Digilent Pmod KYPDキーボード 、内蔵ADC、およびNokia LCDディスプレイを使用して、さまざまな周辺機器をMIPSfpgaシステムに接続する方法について説明します。
MIPSfpgaを他のボードに移植し、周辺機器をシステムに統合します。 パート2