オリジナルCPU「DL166」のレジスタをLEDドットマトリックスで見える化するオリジナルCPUでバイナリコード入門(6)(1/3 ページ)

オリジナル4ビットCPUを用いてバイナリコードを学ぶ本連載。第6回は、「Tang Nano 9K」に移植したオリジナルCPU「DL166」のレジスタをLEDドットマトリックスで見える化する。

» 2023年07月18日 07時00分 公開
[今岡通博MONOist]

はじめに

 今回の作業では、オリジナルCPU「DL166」のレジスタをLEDドットマトリクスで見えるようにします。LEDドットマトリックスは、連載第4回記事で「Tang Nano 9K(以下、Tang Nano)」の基板上にはんだ付けした8×8のLEDドットマトリクスを使います。DL166の8つのレジスタはドットマトリクスに表示しますが、c_flagについては、Tang Nanoの基板に搭載されている6つのオレンジ色のLEDの中から1つを使います。

 DL166をTang Nanoに移植した前回記事では、Verilog-HDLのソースコードは、cpu、ram(メモリ)、testbenchという3つのモジュールに分かれていました。中でも、testbenchは他のFPGAボードにポーティング時に大きな役割を果たします。このtestbench内にプラットフォームであるTang Nanoに依存するコードを収めてしまいます。このようにしておけば、他のプラットフォームに替えた場合も、このモジュールのみに手を加えればよいことになります。

 各モジュールは特定の役割を持たせるように設計されています。機能を追加もしくは変更する場合、そのモジュールのみに変更を加えればよいことになります。……というように、モジュール分割を上手に施しておけば、読みやすいコードになりますしメンテナンス性も増します。

 良いことずくめと思えるモジュール分割なのですが、今回のようにCPUのレジスタの中身を見たいという用途には少し考慮する必要があります。モジュール分割は、それぞれのモジュールの独立性を重んじる発想です。モジュールで管理する変数などのリソースは、引数を介してでないとやりとりできません。今回のように、DL166のレジスタ群をLEDドットマトリクスで見える化するというテーマではかえってコードが煩雑になります。

 もう少し全体が複雑になればモジュール化するメリットもあるでしょうが、本稿執筆時は1つのモジュールに統合したとしても50行程度だったので、全体を見渡せる範囲かと考え、この方針でDL166を再度コーディングすることにしました。いずれもっと機能が追加されて、1つのモジュールではコードの見通しが悪くなって可読性や保守性を損なうようであれば複数のモジュールに分割するかもしれません。現時点では取りあえず手早く動作するものを作ってみて、フィードバックと改善のイテレーションを速く回すことを優先させました。

⇒連載「オリジナルCPUでバイナリコード入門」バックナンバー

3つのモジュールを1つに統合

 前回記事まで、cpu、ram、testbenchという3つのモジュールに分割されていましたが、今回はこれらをcpuモジュールに統合しました。そのメリットは2つあります。1つは、cpuモジュール内部でしか見えなかったregsの値やc_flagの値がモジュール内のどこからでも参照できるようになったことです。もう1つは、今まで別モジュールであったメモリの内容についても、C言語でいうところの配列の添え字でアクセスできるようになったことです。

 それでは早速ソースコードを見ていきましょう。 以下のリスト1はcpuモジュールの1〜10行目です。

1:module cpu(input rst,input clk,
2:    input[3:0] btn,
3:    output [7:0]col, output [7:0]row,
4:    output [5:0]leds);
5:
6:  wire [7:0]dout;
7:	reg c_flag;
8:	reg [3:0]regs[7:0];
9:  reg [7:0]ram[15:0];
10: reg [23:0] counter;
リスト1 cpuモジュールに当たるコード

 1〜4行目は、モジュール名のcpuとこのモジュールの外部とやりとりする入出力を定義しています。

 1行目のrstとclkはいずれも1ビット長の入力として定義されていますが、以前のcpuでも定義されていたものですので説明は省きます。2行目は4ビット長のbtnです。本来は4個のタクトスイッチあるいはディップスイッチを想定しているのですが、Tang Nanoの基板にはそれらに相当する入力は用意されていないので、今回は未接続で使用しています。これらを読み出すと4ビットとも1が返ってきます。3行目のcolとrowはいずれも8ビット長の出力として定義しています。こちらも、LEDドットマトリクスの記事で説明していると思いますので説明は省きます。4行目の6ビット長のledsは、Tang Nanoの基板上に6つ並んだオレンジ色のLEDに接続することを想定しています(図1)。

図1 「Tang Nano」のピン配置とLED、リセットボタンの位置 図1 「Tang Nano」のピン配置とLED、リセットボタンの位置[クリックで拡大]

 6行目の8ビット長のdoutは、フェッチされた命令セットがセットされます。7行目のc_flagは、1ビット長のキャリーフラグが格納されます。8行目では、CPUが操作する4ビット長で8個のレジスタの値が格納されます。9行目では、今まで外部メモリとして用いてたramモジュールをcpu内部の8ビット×16のレジスタとして定義しています。10行目の24ビット長のcounterは、クロックの分周などで用いられます。11行目の3ビット長のiは、counterの13〜15ビット目の3ビットにアサインされています。

       1|2|3 次のページへ

Copyright © ITmedia, Inc. All Rights Reserved.