公開日:2023/11/25
title.png

28th Season


#28-3 RAMマクロの用途

 新しいFPGAボードであるCmod A7ボードで開発中のオリジナル16ビットCPUコアMoscoviumに於いて、前回、Xilinx Artix-7ファミリの大容量RAMマクロをたっぷり使った、メインメモリの拡張を実施しました。
 同時に、RAMマクロには、メインメモリ以外にも使い道があるという話も致しました。

 今回は、RAMマクロの、メインメモリ以外の用途である日本語フォントFONTJPユニットと、unicode⇔S-JIS変換UNISJIユニットを移植して行きます。

日本語フォントFONTJPユニット

 以下の記事で設計した、8×8ドット日本語フォントデータを読み出し可能なI/Oユニットです。

  「#18-4 Moscoviumと日本語フォント

 軽く「おさらい」しながら、移植のポイントを押さえて行きましょう。以下にFONTJPユニットのブロック図を示します。

a184_fontjp.png

※薄黄色の箱はCPUからアクセス可能なI/Oレジスタ、薄緑色の箱はハードマクロ、青破線はRTLとハードマクロの境界線です。

 記憶データは1ドット当たり1ビットなので、フォントデータは1文字=8×8ドット=64ビットのデータを占めます。フォントROMには、1サイクルで1文字分のフォントデータを読み出すことができるよう、64ビット幅のROMマクロを使っています。
 1サイクルで64ビット読み出せれば良いので、普通のシングルポートROMマクロを使っています。回路部分は純粋なRTLなので、Vivadoでもそのまま論理合成可能です。ROMマクロ部分だけをVivadoの36KビットRAMマクロに合わせて変更すれば良いのです。

 使用した36KビットRAMマクロ数は、こちらで確認してください。

フォントROMデータの生成

 フォントROMに記憶するデータは、以下にリンクするOlive+のスクリプトで各自生成して使ってもらいます。詳しい生成手順は、こちらをご覧ください。

  スクリプト:fontjp_gen_mif.olv

※スクリプトを実行するには、拙作Olive+をWindowsにインストールする必要があります。

 以前使っていたPrimerボード(中華製FPGA、👎thumbs-down)では、あまり馴染みのないMIFファイルと言う形式でROMデータを指定していました。
 新しいCmod A7ボードのVivadoでは、Verilog-HDLが規定するMEMファイル形式のファイルを使うことができます。

 スクリプト先頭付近の変数gen_vlog_memを以下の様に設定して生成してください。

  var gen_vlog_mem=true;   // Verilog-HDL用MEMファイルを生成する

※ダウンロードした状態だと、「false」となっていて、MIFファイルが出力されます。

 完成したファイルを「fontjp.mem」にリネームして、Vivadoプロジェクトディレクトリの所定のディレクトリにコピーします。

  ディレクトリパス:MCOC_HDL/ip/fontjp.mem

 Githubに登録されているファイル(fontjp.mem)は中身が空のダミーなので、生成したファイルで上書きしてください。

unicode⇔S-JIS変換UNISJIユニット

 以下の記事で設計した、unicode⇔S-JISコード間の相互変換が可能なI/Oユニットです。

  「#22-1 文字コード変換回路

 軽く「おさらい」しながら、移植のポイントを押さえて行きましょう。以下にFONTJPユニットのブロック図を示します。

a221_unisji.png

※薄黄色の箱はCPUからアクセス可能なI/Oレジスタ、薄緑色の箱はハードマクロ、青破線はRTLとハードマクロの境界線です。

 「逆引き」とは即ち、テーブル全体を検索して合致するデータを見つける作業です。
 上に示したブロック図の通り、同時に12文字分のデータを検索して一致するデータを見つけるため、変換テーブルROMは、1サイクルで12文字分のデータ、従って12文字×16ビット(※)=192ビットのデータを読み出す必要があります。
 192ビットのシングルポートROMを使っても良かったのですが、96ビットのデュアルポートROMとして、2つのポートから別々なアドレスを読み出すことで、192ビット/1サイクルの読み出しを実行しました。
 この様に単純な作業を並列して同時に実行できるのは、ソフトウェアには真似できない、ハードウェアの特権です。

※16ビットunicodeが対象のため。

 回路部分は純粋なRTLなので、Vivadoでもそのまま論理合成可能です。ROMマクロ部分だけをVivadoの36KビットRAMマクロに合わせて変更すれば良いのです。

 使用した36KビットRAMマクロ数は、こちらで確認してください。

変換テーブルROMデータの生成

 変換テーブルROMに記憶するデータは、以下にリンクするOlive+のスクリプトで各自生成して使ってもらいます。詳しい生成手順は、こちらをご確認ください。

  スクリプト:unisji_mkmif.olv

※スクリプトを実行するには、拙作Olive+をWindowsにインストールする必要があります。

 以前使っていたPrimerボード(中華製FPGA、boooo👎)では、あまり馴染みのないMIFファイルと言う形式でROMデータを指定していました。
 新しいCmod A7ボードのVivadoでは、Verilog-HDLが規定するMEMファイル形式のファイルを使うことができます。

 スクリプト先頭付近の変数gen_vlog_memを以下の様に設定して生成してください。

  var gen_vlog_mem=true;   // Verilog-HDL用MEMファイルを生成する

※ダウンロードした状態だと、「false」となっていて、MIFファイルが出力されます。

 完成したファイルを「unisji.mem」にリネームして、Vivadoプロジェクトディレクトリの所定のディレクトリにコピーします。

  ディレクトリパス:MCOC_HDL/ip/unisji.mem

 Githubに登録されているファイル(unisji.mem)は中身が空のダミーなので、生成したファイルで上書きしてください。

デザイン

 Cmod A7ボード用Moscoviumマイコンの設計データ(Vivadoプロジェクト)は、Githubで提供します。以下リンクよりアクセスしてください。

btn_moscovium.png

 ダウンロード方法などについては、トップのREADME.mdをご覧ください。

 今回までに移植を完了したユニットは、以下の通りです。

 これによって、以下の型名が解禁されました。

 この先の実験では、上の中からMCOC115US0816を使いますので、コンパイルしてCmod A7ボード(FPGA)に書き込んでおいてください。
 デザイン(回路)をCmod A7ボードに書き込む手順については、こちらをご確認ください。

コンパイル

 Vivadoでのコンパイル(論理合成・配置配線)結果を以下にまとめます。

  コンパイル結果:

 どういう訳か、UNISJIユニットの変換テーブルROM(96ビット×1,344ライン=15.75Kバイト)に、36KビットRAMマクロ数が5.5個と報告されました(普通に考えると、必要数は6個のハズ)。中途半端なサイズ(非2冪数)のROMなので、どういう理屈か良く解りませんが、深く考えるのは止めました。Vivadoの報告通りに記載してあります。

拡張RAMユニット

 前節の通り、コンパイルしたところ、FONTJPユニットとUNISJIユニットで、合計22個(小数点以下切り上げ)の36KビットRAMマクロを使いました。命令ROMサイズを最小の4Kバイト(RAMマクロ1個)に抑えたとしても、残った27個で構成可能な拡張RAM(ERAM)ユニットは、最大108Kバイト(=4Kバイト×27個)分です。最大の2冪数に切り下げると、ようやく64Kバイトを確保できる、と言う所ですね。
 やはり、仕様上最大とした128Kバイトは確保できないのね……。

 この様な実例の通り、RAMマクロが大量に必要なアプリケーションを作るのであれば、もっと上位のFPGAチップ(Artix-7ファミリXC7A100T等)を使う事を検討してください。

※「大は小を兼ねる」ので、なるべく上位のチップを選択するのは間違いではありませんが、上位チップは高額になるので、費用対効果を考えた上で選択するべきです。

実験用プログラム

 シリアルモニタから文字列を受信して、外部OLEDディスプレイ(下図)に表示するプログラムを作り、後ほど実験に使います。

a222_oledisp.jpg


 以下に、完成したプログラムをリンクしておきます。

  プログラム:oled_kprint.asm

 こちらに従ってアセンブルし、Cmod A7ボードに転送してお使いください。Moscoviumマイコンに転送すると、シリアルモニタから、以下のコマンドを受け付けています。

  コマンド仕様:

 動作検証の手順としては、【prn】コマンドでFONTJPユニットの動作を確認したら、【uprn】コマンドでUNISJIユニットの動作を確認する、と言う順番です。

モジモジ描画実験

 実験の準備として、Cmod A7ボードとOLEDディスプレイを以下の様に接続してください。

Cmod A7ボード
(Moscoviumマイコン)
接続 OLEDディスプレイ
VU (VBUS、5V) VCC
GND GND
stws_scl (18 PIN) SCL
stws_sda (19 PIN) SDA

 Moscoviumマイコンのピン配置表はこちらです。デザインはMCOC115US0816をCmod A7ボード(FPGA)へ書き込んでおいてください。
 OLEDディスプレイは、ボード上のレギュレータで3.3Vへ降圧しているので、VCCには5Vを接続します。I2C端子は3.3V定格なので、Cmod A7ボードと直結できます。詳しくはこちら


 以下に、実験中の様子を示します。

a283_expr.jpg

 以降、Cmod A7ボードとの通信は、S-JISおよび、UTF-8符号化した日本語文字列を送受信できる必要があるので、Tera Term等、文字符号化方式を設定可能なターミナルソフトを使用してください。


 Tera Termから、「KanjiCodeメニュー ⇒ Recv/Send: Shift_JIS」を実行して、S-JIS符号化に設定したら、以下サンプルの様に実験を始めましょう。

  実験サンプル:【 】内はシリアルモニタからの送信データ
  【prn,0,S-JISエンコード文字列】
  OK: prn

 OLEDディスプレイにS-JIS符号化した文字列が表示されたはずです。
 プログラムの動作としては、FONTJPユニットからS-JISコードのフォントデータを取り出して、OLEDディスプレイに描画しました。FONTJPユニットが正常に機能していなければ、OLEDディスプレイに正しく表示されないはずです。


 今度はTera Termで「KanjiCodeメニュー ⇒ Recv/Send: UTF-8」を実行し、UTF-8符号化に設定して続けます。

  【uprn,1,UTF-8変換、表示サンプル】
  OK: uprn

 UTF-8で送信した文字列データをプログラム(oled_kprint.asm)がUTF-8 → unicode → S-JIS変換(UNISJIユニット)して、OLEDディスプレイに描画しました。UNISJIユニットが正常動作していない場合は、文字化けしたデータが表示されてしまうはずです。

 当方の実験では、図に示した通り、正常に表示されました。OKです。実験を終了します。


 こうして見ると、フォントROMは結構なサイズですね。これでも8×8ドットの日本語フォントで妥協しているのですがね……。複雑な漢字まで視認可能な16×16ドットフォントではROMサイズが×4倍となって、XC7A35TのRAMマクロでは足りなくなってしまいます。中々……。


btn_arduino.png

btn_prev.png btn_next.png

home