オリジナル4ビットCPUを用いてバイナリコードを学ぶ本連載。第9回では、プログラミング演習の定番であるLチカを題材にバイナリコードを動かしてみる。
前回に引き続き、オリジナル4ビットCPU「DL166」を用いたバイナリプログラミングの演習をはじめます。「たかがLチカされどLチカ」と題して、LEDのさまざまな点滅(Lチカ)のさせ方に挑戦してみたいと思います。
⇒連載「オリジナルCPUでバイナリコード入門」バックナンバー
「Tang Nano 9K(以下、Tang Nano)」にLEDドットマトリクスを搭載したものを用います。連載第4回記事『新たな教材となる「Tang Nano 9K」を使ってLEDマトリクスを制御する』を参考にしてください。また、LEDマトリクスの見方は連載第8回「2行で書けるバイナリコードを動かしてみよう」が参考になります。
Tang Nano搭載のFPGAの製造元であるGOWIN SemiconductorのIDE(統合開発環境)も必要です。インストール時にドキュメントがダウンロードされますのでそれを参考にしてください。これらのドキュメントには日本語版も含まれています
本記事で紹介するVerilog-HDLを用いたサンプルコードは以下のGitHubのリポジトリから入手したください。
⇒DL166の命令セットのプロジェクトがあるGitHubのリポジトリはこちら
また、本記事で紹介するサンプルコードにおけるの命令セットの意味や使い方は、DL166の仕様を紹介した連載第1回記事『オリジナル4ビットCPU「DL166」はプログラミングの基礎学習に最適』を参考にしてください。
これまでの連載において、Tang Nanoに装着したLEDドットマトリクスで表示していたのはDL166の内部の8個のレジスタの値でした。まずは、これを利用してLチカプログラムのblink1.asm(リスト1)を作ってみましょう。
ram[0] <=8'b1010_0001; // mvi R0,1 ram[1] <=8'b1010_0000; // mvi R0,0 ram[2] <=8'b1001_0000; // jmp 0
ramの0番地にmvi R0,1を意味する1010_0001を代入しています。この命令ではレジスタR0に1を入れます。2進表記の1010_0001の“_(アンダーバー)”は、ビット列の区切りを見やすくするためのものであってもなくても大丈夫です。この例だと、1010がmviを示しアンダーバーの後の0001はR0に代入する値となります。最初の4桁が命令セットでいうところのオペレーターで後の4桁がオペランドとなります。オペレーターはCPUに何をさせるかを指示するもので、オペランドはその命令を実行するための値となります。
次はramの1番地にmvi R0,1を意味する1010_0000を代入しています。この命令はレジスタR0に0を入れます。次はramの2番地にjmp 0を意味する1001_0000を代入します。この命令は実行を0番地に戻します。プログラムとしてはmvi R0,1とmvi R0,0を繰り返す動作となります。
それでは、実際に動かしてみましょう。/src/instructions.vの29〜31行目をリスト2のように書き換えてから、GOWINのIDEでSynthesizeとPlace & Route、そして最後にProgram DeviceでTang Nanoの評価モジュールに書き込んでください。
initial begin `include "blink1.asm" end
評価モジュールのUSBポートを左に向けた状態で、LEDドットマトリクスの最上段左端のLEDが点滅していませんか(図1)。ただし、LEDの光っている時間と消えている時間が同じではないですよね。
なぜこうなっているかというと、途中でjmp 0命令を実行するのにもう1クロック分の時間が必要なので、LEDが光っている時間が1クロックであるのに対して消えている時間が2クロックになっているからです。今回のDL166の実装では1クロックが約1秒になっています。ちなみに図1ではレジスタR0が1になってLEDが光っています。
なお、LEDドットマトリックスの最下段左端のLEDも光っているのですが、これはレジスタR7のプログラムカウンタの値です。
Copyright © ITmedia, Inc. All Rights Reserved.