動かしてわかるCPUの作り方10講(技術評論社)

SL (左シフト)、SR (右シフト)、SRA (算術右シフト)の各命令を74シリーズで実装する

まずSL、SR、SRAをそれぞれ実装する。 SL: SR: SRA: 全部組み合わせる。 以下の3つを確かめる。 OP_CODEが5のときに左に1ビットシフトすること。 OP_CODEが6のときに右に1ビットシフトすること。 OP_CODEが7のときに、全体が右に1ビットシフトするが、最上位…

AND命令とOR命令とをひとつにまとめる

動作は前々回および前回と同じである。

OR命令を74シリーズで実装する

配線が面倒なのでprimitivesのOR2シンボルを使うことにする。 OP_CODEが4のときにビットORの実行されることを確かめる。今、0xABCD | 0x4567 = 0b 1110 1111 1110 1111を計算している。

AND命令を74シリーズで実装する

配線が面倒なのでprimitivesのAND2シンボルを使うことにする。 OP_CODEが3のときにビットANDの実行されることを確かめる。今、0xABCD & 0x4567 = 0b 0000 0001 0100 0101を計算している。

ADD命令およびSUB命令を74シリーズで実装する

まず4ビット加算器74283を4ビット加減算器にする。 参考: トランジスタ技術 2020年 5月号, pp.87-89 それを4つつないで16ビット加減算器にする。 それを使ってADD命令およびSUB命令を実装する。 以下の3つを確かめる。 OP_CODEが1のときに足し算の実行される…

MOV命令を74シリーズで実装する

レジスタBをレジスタAに上書きする命令である。 OP_CODEが0のときだけ以下の状態になることを確かめる。 REG_Bがそのまま出力されること。 REG_WENからHiが出力されること。 RAM_WENからLoが出力されること。 PC_LD_NからHiが出力されること。

プログラムカウンターを74シリーズで作る

『CPUの創りかた』と同じく74161を使う。テキストのVHDLは同期リセットにしてあるが、ここでは非同期リセットにした。 以下の3つを確かめる。 クロックに連動して0~255までカウントアップすること。 RESET_N信号をLoにしたときにクロックとは無関係に即座に…

RAMの読み出し部を回路図エディターで作る

RAMの読み出し部を作る -と同じ動作をする回路を回路図エディターで作る。74シリーズで作るのはあとまわしにして、まずはmegafunctionsで楽に作って全体のロジックだけ確認する。最終的にはIO65_IN[15..0]を外部からのINポートに使うとの由。 RAM_0~7[15..0…

RAMの読み出し部を作る

pp.198-200 これもテキストのままである。16ビット×256本のRAMのうち1本を選んで出力する。ただしここでは8+1本のなかから選べるようにした。 -- ram_dc.vhd library IEEE; use IEEE.std_logic_1164.all; entity ram_dc is port( CLK_DC : in std_logic; RAM…

レジスタの読み出し部を74シリーズで作る

レジスタの呼び出し部も74シリーズで作ってみる。バスの選択にはマルチプレクサではなく3ステートバッファーを使うことにした。動作は前回のVHDLと同じである。配線が面倒なのでD-FFおよび3ステートバッファーはprimitivesのシンボルを使った。ここでもやは…

レジスタの読み出し部を作る

pp.197-198 16ビット×8本のレジスタのうち1本を選んで出力する。これもテキストのままである。 -- reg_dc.vhd library IEEE; use IEEE.std_logic_1164.all; entity reg_dc is port( CLK_DC : in std_logic; N_REG_IN : in std_logic_vector(2 downto 0); -- …

デコード部を74シリーズで作る

デコード部も74シリーズで作ってみる。74175 (Dフリップフロップ4個入り)も74273 (Dフリップフロップ8個入り)も十分に流通している。動作は前回のVHDLとまったく同じである。

デコード部を作る

p.197 これもテキストのままである。15ビットから成るマシン語の上位4ビット(オペコード)と下位8ビット(オペデータ)とを抜き出して出力する。テキストにも書いてあるように、今作ろうとしているCPUには実は不要。 -- decode.vhd library IEEE; use IEEE.std_…

ROM部を作る

pp.195-196 これもテキストどおりである。この段階ではVHDLの中にマシン語を直接記述している(すなわちROM (のようなもの)をLEで実現している)が、最終的にはメモリーブロックに移すとの由。 -- fetch.vhd library IEEE; use IEEE.std_logic_1164.all; use I…

74シリーズで4相クロックを作る

今度は、74175 (Dフリップフロップ4個入り、共通クロック、ポジティブエッジトリガー)で同じことをしてみる。動作は前回のVHDLとまったく同じである。CLKに1 MHzを与えて、ロジアナで4相クロックを観測した。 74175は今も十分に流通している。

VHDLで4相クロックを作る

これまでMAX V (5M240ZT100C5N)を使ってきたが、今回からMAX 10 (10M08SAE144C8G)を使う。 pp.193-195 いわゆるone-hot state counterである。下のコードはテキストのままである。 -- clk_gen.vhd library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_…

74シリーズの10進同期カウンター74162を使ってみる

(テキストとは無関係) 74シリーズにもカウンターはたくさんある。ここでは同期プリセット、同期リセット、リプルキャリー出力つきの10進同期カウンター74162を使ってみる。プリセットもリプルキャリーも使わないので、動作は前回のVHDLとまったく同じである。

VHDLで10進同期カウンターを作る

pp.121-122 今度は、同期リセットつきの10進同期カウンターを作る。0 → 9のカウントアップを繰り返すカウンターである。 これだと、何進カウンターであろうと自由自在に作れることになる。 library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_u…

プロセス文でポジティブエッジトリガー型Dフリップフロップを作る

pp.120-121 今度はプロセス文で順序回路Dフリップフロップを作ってみる。 library IEEE; use IEEE.std_logic_1164.all; entity d_ff is port( CLK, D : in std_logic; Q : out std_logic ); end d_ff; architecture RTL of d_ff is begin process(CLK) -- CL…

74シリーズの7セグメントデコーダー74248を使う

74シリーズにも7セグメントデコーダーは当然何種類かある。ここでは74248 (IC自体は市場から消えた)を使ってみる。 参考: トランジスタ技術 2019年 12 月号, pp.95-96 今、3を表示している。

プロセス文で7セグメントデコーダーを作る

pp.117-118 論理式でも記述できないことはないがプロセス文のほうが遙かに容易である。 テキストはアノードコモンを使っているが、手持ちはカソードコモンしかなかったので、ここではカソードコモンを使う。したがって論理はテキストとは反転する。 library …

VHDLで4ビット加算器を作る / ライブラリーを使う

pp.114-116 今度はライブラリーを使って4ビット加算器を作ってみる。ただの足し算で表現できる。 5LEを消費した。 library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_unsigned.all; -- usigned数を演算するためのlibraryを使う。 entity adder…

VHDLで4ビット加算器を作る / 全ビットを全加算器にしてみる

前回はテキストどおりにビット0だけを半加算器にしたが、今度は全ビットを全加算器にしてみる。 8LEを消費した。 library IEEE; use IEEE.std_logic_1164.all; -- 4ビット加算器の入出力を宣言する。 entity adder_4bit is port( AIN : in std_logic_vector(…

VHDLで4ビット加算器を作る / ビット0だけ半加算器にする

pp.111-114 今度は、前回作った全加算器を連結して4ビット加算器を作ってみる。ビット0だけはキャリーインが不要なので半加算器にする。 7LEを消費した。 library IEEE; use IEEE.std_logic_1164.all; -- 4ビット加算器の入出力を宣言する。 entity adder_4b…

VHDLで全加算器を作る

pp.109-111 今度は全加算器を作ってみる。 前回作ったhalf_adder.vhdをfull_adder.vhdと同じフォルダに入れておき、その半加算器をfull_adder.vhd側でコンポーネントとして宣言し、それを2つ実体化して連結する。 library IEEE; use IEEE.std_logic_1164.all…

VHDLで半加算器を作る

pp.108-109 要領はわかったので今度は半加算器を作ってみる。入出力ポートを宣言して、その入力と出力との関係を定義すればよい。 library IEEE; use IEEE.std_logic_1164.all; entity half_adder is port ( A : in std_logic; B : in std_logic; S : out st…

VHDLで基本ゲートを作る

動かしてわかる CPUの作り方10講, pp.376ff. ファイルを作るときに[Block Diagram/Schematic File]ではなく[VHDL FIle]を選ぶのを除けば、書き込みまでの全体の手順は回路図エディタのときと同じであった。 -- ダブルハイフンでコメントアウト -- #include <stdio.h></stdio.h>…

CPUエミュレーター

pp.48ff. テキストからはかなり書き換えた。and、orは&&、||の代替表現として予約されているようなので、下のコード例ではひとまず_and、_orにしてエスケープしておく。 #include <iostream> #include "CPU_emulator_0.h" /* ニモニック(のようなもの)一覧 mov(ra, rb)</iostream>…

インラインアセンブラ(x86系MASM, Microsoft Macro Assembler)

動かしてわかる CPUの作り方10講, pp.17-20 1+2+ ... +10=55を計算する。 #include <iostream> int main(void){ uint16_t sum; __asm { mov ax, 0 mov bx, 1 LOOP1: cmp bx, 11 // cmpはcompare je MOUT // jeはjump if equal add ax, bx inc bx jmp LOOP1 MOUT: mov </iostream>…