動かしてわかるCPUの作り方10講(技術評論社)
74シリーズはあきらめてmegafunctionsを使うことにする。クロックのタイミングで16ビット×8本のうち1本を選んで更新する。
テキストどおりVHDLで記述していた回路をシンボルで書き換える。これは単純なので問題ない。
テキストは、VHDLで組んだ二進 → 十進変換回路でOUTポートのデータを十進数に変換し、それを5桁の7セグLEDで表示している(pp.221ff.)。 ここでは、せっかくCPUを作ったのでソフトウェアで解決してみる。たとえば0d54321は次の手順で各桁を取り出す。詳細不明…
############################ # アセンブラ(のようなもの) # ############################ import math def constrain(val, _max, _min): return int(min(max(val, _min), _max)) def generate_mif(file_name, width, depth, rom): f = open(file_name, "w…
3.3 Vで直接動かせるSC1602BBWB-XA-LB-Gを使う。PIC16F1789/1939 & MPUトレーナー カテゴリーの記事一覧 -の評価基板に載っていたのを外した。8ビットモードで動かす。 下のように接続する。 CPUのOUT[7:0] → LCDのDB[7:0] CPUのOUT[8] → LCDのRS CPUのOUT[9…
sra命令を廃止する。代わりに、即値ではなくレジスタでジャンプ先が指定できる命令を追加する。exec_jnc.vhdのsra命令の部分を下のように書き換える。 --when "0111" => -- SRA -- REG_IN_TEMP <= '0' & REG_A(15) & REG_A(15 downto 1); --REG_WEN <= '1'; …
今度は、hlt命令を廃止してjnc (jump if no carry)命令を追加する -で追加したjnc命令を使ってLチカをしてみる。ビジーループ自体は2命令で済む。もっと遅くしたい場合はnop命令を挟む。nopも4クロックを要する。 F_CPU = 10E3 DELAY = 0.5 # sec LOOPS = in…
register /レジスタ/ resistor /リズィスタ/ reg_dc、reg_wbの入出力を2次元化する。VHDLでの記述方法がわからないため回路図エディターを使った。 変更前: 変更後:
/ディーコウドゥ/ p.178, p.182 結局第10講には進まず、パイプライン化はしないことにしたので、decodeコンポーネントは要らなくなった。下のように取り外して配線し直す。 変更前: 変更後:
今度は、『動かしてわかるCPUの作り方10講』第9講までのCPUと、テキストとは別に追加したjnc命令とを使って割り算をしてみる。値はunsigned shortであると見なす。 0xABCD ÷ 0x0123 = 0b 0000 0000 1001 0111を計算した。 .mifファイルを生成するアセンブラ…
テキストは加減算のキャリー、ボローを見ていないため少し不便である。そこで、hlt (停止)命令はよして代わりにjnc (jump if no carry)命令を追加する。要は、キャリービットを含む17ビットの信号REG_IN_TEMPを追加しただけである。hltの代用はjmp 自番地と…
今度は掛け算をしてみる。 今、0x0010 * 0x0876 = 0b 1000 0111 0110 0000を計算したところである。 def generate_mif(file_name, width, depth, rom): f = open(file_name, "w") f.write("WIDTH=%d;\n" % width) f.write("DEPTH=%d;\n" % depth) f.write("A…
クロックは10 kHzにしてある。すべての命令が実行に4クロックを要する。 ROMの初期化データである.mifファイルを生成するためのアセンブラのようなもの: def generate_mif(file_name, width, depth, rom): f = open(file_name, "w") f.write("WIDTH=%d;\n" %…
pp.290ff. 今度は、ROMと同じ要領でRAMもメモリーブロックへ移す。これでRAMは0~63番地まで使えるようになった。ただ、クロックの変更に関する理解が追いつかないため、テキストのVHDLのままシンボル化して配線するにとどめる。 テキストは最後の第10講でパ…
pp.274-276 コメントを足した以外はテキストのままである。 library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_unsigned.all; entity ram_dc_wb is port( CLK_DC : in std_logic; CLK_WB : in std_logic; RAM_ADDR : in std_logic_vector(7 do…
pp.256ff. これまでROM (プログラムメモリー)は、15ビット×16本だけをLEで実装していたが、今度は15ビット×256本のROMをメモリーブロック上に作る。手順はROM: 1-PORTの使いかた -に示した。初期化データである.mifファイルを生成するためのアセンブラのよう…
def generate_mif(file_name, width, depth, rom): f = open(file_name, 'w') f.write("WIDTH=%d;\n" % width) f.write("DEPTH=%d;\n" % depth) f.write("ADDRESS_RADIX=UNS;\n") f.write("DATA_RADIX=BIN;\n") f.write("CONTENT BEGIN\n") format_of_code =…
pp.239ff. 前回までは、外部のFGからクロックを供給していた。今度は、評価ボードに実装されている48 MHz発振器(27番ピンに接続)からクロックを供給する。極端に遅くしたクロックを供給することにより、動作が目で追えるようにする。 テキストは、VHDLで構成…
今度は、モジュールごとにシンボル化してそれぞれを回路図エディターで結線してみる。中身はあいかわらずテキストのVHDL (pp.186-207)のままである。動作は前回とまったく同じ。
pp.216ff. テキスト第1部までのcpu15.vhd (pp.186-207)をそのまま動かしてみる。 ピンアサインは下のようにした(参考: 『MAX10実験キットで学ぶFPGA&コンピュータ (トライアルシリーズ)』)。今使っている評価ボードMAX10-FB (10M08SAE144C8G)にも発振器(48 M…
構造は、レジスタへの書き込み部と同じである。無駄を承知で8:256のデコーダーで256本まで選べるようにしたが、ここではテキストどおりに8+1本だけ実装した。クロックのタイミングで1本だけを書き換える。IO64_OUTを外部へのOUTポートに使う。 これも動作は…
ここに、8本×16ビットの汎用レジスタを実装する。クロックのタイミングで1本だけを書き換える。 これも動作は未確認。
動作は未確認。
halt命令。これで全16命令が一往実装できた。 /ホーるトゥ/
汎用レジスタの値をRAMへ格納する命令。
RAMからレジスタへデータを持ってくる命令。
PCを強制的に書き換える命令。
CMP_FLAGがHiのときにはPCを即値で書き換える。 CMP_FLAGがLoのときにはPCをカウントアップする。
74シリーズにコンパレーターはいくつかあるがここでは74684を使うことにする。 OP_CODEが10のときに2つの16ビットレジスタが同士が一致したらコンペアフラグが立つ。それ以外のOP_CODEのときは出力がオフになる。
まずLDLを実装する。 次にLDHを実装する 2つを組み合わせる。 以下の2つを確かめる。 OP_CODEが8のときに下位バイトだけが書き換えられること。 OP_CODEが9のときに上位バイトだけが書き換えられること。 0xFFFFの下位バイトを0xAAで書き換える。 0xFFFFの上…