0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

概要 

windowsでiverilogやってみた。
8bit CPU、書いてみた。

8bitCPUで、何ができる。

fizzbuzzを100まで、数えることができる。

1. 基本命令一覧

引数(opland)がない命令は、下位8ビットを8'h00(00000000)として処理するのが一般的です。

ニーモニック 動作説明 スタック変化 機械語 (2進数 [11:0]) 機械語 (16進数)
HALT プログラムの実行を停止(PCを固定) なし 0000_00000000 12'h000
PUSH v 8ビット即値 v をスタックに積む [ → v ] 0010_vvvvvvvv 12'h2vv
ADR a ジャンプ先アドレス a(6bit)をセット なし 0011_00aaaaaa 12'h3aa
JEQ q[0]==1 以外なら adr へジャンプ、実行後ポップ [ q[0] → ] 0100_00000000 12'h400
OUT スタックトップの値を外部出力し、ポップ [ q[0] → ] 0101_00000000 12'h500
DUP スタックトップの値を複製(EXT 8'h20 と同等) [ → q[0] ] 1000_00000000 12'h800
DROP スタックトップの値を1つ破棄(EXT 8'h21 と同等) [ q[0] → ] 1001_00000000 12'h900

2. 条件付きジャンプ拡張命令

仕様書によると、op = 4'h4(JEQ)の挙動が下位8ビット(opland)によって以下のように変化・拡張されます。

ニーモニック 動作説明 スタック変化 機械語 (2進数 [11:0]) 機械語 (16進数)
IF0 q[0] == 0 なら adr へジャンプ、実行後ポップ [ q[0] → ] 0100_00000000 12'h400
IF1 q[0] == 1 なら adr へジャンプ、実行後ポップ [ q[0] → ] 0100_00000001 12'h401
jmp 無条件で adr へジャンプ、実行後ポップ [ q[0] → ] 0100_00001111 12'h40F

3. 拡張演算・システム命令一覧(EXT: op = 4'hF)

上位4ビットが 4'hF(1111)となり、下位8ビット(opland)で具体的な演算を指定する命令群です。

算術・論理演算

ニーモニック 動作説明 スタック変化 (前 → 後) 機械語 (2進数 [11:0]) 機械語 (16進数)
+ 加算(q[1] + q[0]) [ q[1], q[0] ] → [ 答 ] 1111_00000000 12'hF00
- 減算(q[1] - q[0]) [ q[1], q[0] ] → [ 答 ] 1111_00000001 12'hF01
* 乗算(q[1] * q[0]) [ q[1], q[0] ] → [ 答 ] 1111_00000010 12'hF02
/ 除算(q[1] / q[0])※0除算は0 [ q[1], q[0] ] → [ 答 ] 1111_00000011 12'hF03
mod 剰余(q[1] % q[0])※0除算は0 [ q[1], q[0] ] → [ 答 ] 1111_00000100 12'hF04
= 比較(等しければ1、違えば0) [ q[1], q[0] ] → [ 1 or 0 ] 1111_00001111 12'hF0F
< 比較(q[1] < q[0] なら1、違えば0) [ q[1], q[0] ] → [ 1 or 0 ] 1111_00010000 12'hF10
> 比較(q[1] > q[0] なら1、違えば0) [ q[1], q[0] ] → [ 1 or 0 ] 1111_00010001 12'hF11
max 大きい方の値を選択 [ q[1], q[0] ] → [ 最大値 ] 1111_00010012 12'hF12
min 小さい方の値を選択 [ q[1], q[0] ] → [ 最小値 ] 1111_00010013 12'hF13
and ビット論理積(q[1] & q[0]) [ q[1], q[0] ] → [ 答 ] 1111_00010100 12'hF14
or ビット論理和(q[1] q[0]) [ q[1], q[0] ] → [ 答 ] 1111_00010101
invert ビット反転(※ポップなし) [ q[0] ] → [ ~q[0] ] 1111_00010110 12'hF16

スタック操作(Forth互換)

ニーモニック 動作説明 スタック変化 (前 → 後) 機械語 (2進数 [11:0]) 機械語 (16進数)
dup スタックトップを複製して積む [ q[0] ] → [ q[0], q[0] ] 1111_00100000 12'hF20
drop スタックトップを1つ削除 [ q[0] ] → [ ] 1111_00100001 12'hF21
swap 上位2つの値を入れ替える [ q[1], q[0] ] → [ q[0], q[1] ] 1111_00100010 12'hF22
over 上から2番目の値を複製して一番上に積む [ q[1], q[0] ] → [ q[1], q[0], q[1] ] 1111_00100011 12'hF23
rot 上位3つの値を回転(q[2]が最上位へ) [ q[2], q[1], q[0] ] → [ q[1], q[0], q[2] ] 1111_00100100 12'hF24

コンソール出力・デバッグ・特殊

ニーモニック 動作説明 スタック変化 機械語 (2進数 [11:0]) 機械語 (16進数)
. q[0] を「10進数数値」として出力、ポップ [ q[0] → ] 1111_00110000 12'hF30
emit q[0] を「ASCII文字」として出力、ポップ [ q[0] → ] 1111_00110001 12'hF31
cr 改行(\n)を出力 なし 1111_00110010 12'hF32
space 半角スペースを出力 なし 1111_00110013 12'hF33
.s 現在のスタック(q[0]~q[5])を一覧表示 なし 1111_00110100 12'hF34
random 0〜255のランダムな数値を積む [ → 乱数 ] 1111_01000000 12'hF40

サンプルコード

			// ROM PROGRAM: FizzBuzz (1 to 100)
			rom[0]  <= 12'h2_00; // PUSH 0 (ループカウンター初期値)
			// --- [アドレス1] ループ先頭 ---
			rom[1]  <= 12'h2_01; // PUSH 1
			rom[2]  <= 12'hF_00; // +            [Stack: Count] (インクリメント)
			// --- 101終了判定 ---
			rom[3]  <= 12'hF_20; // dup          [Stack: Count, Count]
			rom[4]  <= 12'h2_65; // PUSH 101     [Stack: 101, Count, Count]
			rom[5]  <= 12'hF_0F; // =            [Stack: (Count==101), Count]
			rom[6]  <= 12'h3_3A; // ADR 58       (終了処理アドレス 58 = 16進数3A)
			rom[7]  <= 12'h4_01; // JNE (IF1)    (Count==101 なら終了処理へ)
			// --- FizzBuzz (15の倍数) 判定 ---
			rom[8]  <= 12'hF_20; // dup
			rom[9]  <= 12'h2_0F; // PUSH 15
			rom[10] <= 12'hF_04; // mod          [Stack: (Count%15)]
			rom[11] <= 12'h3_25; // ADR 37       (FizzBuzz出力アドレス 37 = 16進数25)
			rom[12] <= 12'h4_00; // JEQ (IF0)    (余り0ならジャンプ、違えば直進)
			// --- Fizz (3の倍数) 判定 ---
			rom[13] <= 12'hF_20; // dup
			rom[14] <= 12'h2_03; // PUSH 3
			rom[15] <= 12'hF_04; // mod          [Stack: (Count%3)]
			rom[16] <= 12'h3_1B; // ADR 27       (Fizz出力アドレス 27 = 16進数1B)
			rom[17] <= 12'h4_00; // JEQ (IF0)    (余り0ならジャンプ、違えば直進)
			// --- Buzz (5の倍数) 判定 ---
			rom[18] <= 12'hF_20; // dup
			rom[19] <= 12'h2_05; // PUSH 5
			rom[20] <= 12'hF_04; // mod          [Stack: (Count%5)]
			rom[21] <= 12'h3_2F; // ADR 47       (Buzz出力アドレス 47 = 16進数2F)
			rom[22] <= 12'h4_00; // JEQ (IF0)    (余り0ならジャンプ、違えば直進)
			// --- 通常の数値表示 (どの倍数でもなかった場合) ---
			rom[23] <= 12'hF_20; // dup
			rom[24] <= 12'hF_30; // .            (数値を表示&消費)
			rom[25] <= 12'h3_37; // ADR 55       (共通改行アドレス 55 = 16進数37)
			rom[26] <= 12'h4_FF; // JMP          (改行処理へ無条件ジャンプ)
			// --- [アドレス27] Fizz出力処理ブロック ---
			rom[27] <= 12'h2_46; // PUSH 'F'
			rom[28] <= 12'hF_31; // emit
			rom[29] <= 12'h2_69; // PUSH 'i'
			rom[30] <= 12'hF_31; // emit
			rom[31] <= 12'h2_7A; // PUSH 'z'
			rom[32] <= 12'hF_31; // emit
			rom[33] <= 12'h2_7A; // PUSH 'z'
			rom[34] <= 12'hF_31; // emit
			rom[35] <= 12'h3_37; // ADR 55       (共通改行アドレス 55 = 16進数37)
			rom[36] <= 12'h4_FF; // JMP
			// --- [アドレス37] FizzBuzz出力処理ブロック ---
			rom[37] <= 12'h2_46; // PUSH 'F'
			rom[38] <= 12'hF_31; // emit
			rom[39] <= 12'h2_69; // PUSH 'i'
			rom[40] <= 12'hF_31; // emit
			rom[41] <= 12'h2_7A; // PUSH 'z'
			rom[42] <= 12'hF_31; // emit
			rom[43] <= 12'h2_7A; // PUSH 'z'
			rom[44] <= 12'hF_31; // emit
			rom[45] <= 12'h3_2F; // ADR 47       (そのままBuzz出力 47 = 16進数2F へ合流)
			rom[46] <= 12'h4_FF; // JMP
			// --- [アドレス47] Buzz出力処理ブロック ---
			rom[47] <= 12'h2_42; // PUSH 'B'
			rom[48] <= 12'hF_31; // emit
			rom[49] <= 12'h2_75; // PUSH 'u'
			rom[50] <= 12'hF_31; // emit
			rom[51] <= 12'h2_7A; // PUSH 'z'
			rom[52] <= 12'hF_31; // emit
			rom[53] <= 12'h2_7A; // PUSH 'z'
			rom[54] <= 12'hF_31; // emit
			// ※次のアドレス55が共通改行なので、BuzzからはJMPを省略してそのまま直進(フォールスルー)
			// --- [アドレス55] 共通改行&ループバック処理 ---
			rom[55] <= 12'hF_32; // cr           (改行を出力)
			rom[56] <= 12'h3_01; // ADR 1        (ループ先頭へ)
			rom[57] <= 12'h4_FF; // JMP          (ループ先頭アドレス1へ無条件ジャンプ)
			// --- [アドレス58] 終了処理 ---
			rom[58] <= 12'hF_21; // drop         (残ったカウンターを破棄)
			rom[59] <= 12'h0_00; // HALT

実行結果

>vvp a.out
  1
  2
Fizz
  4
Buzz
Fizz
  7
  8
Fizz
Buzz
 11
Fizz
 13
 14
FizzBuzz
 16
 17
Fizz
 19
Buzz
Fizz
 22
 23
Fizz
Buzz
 26
Fizz
 28
 29
FizzBuzz
 31
 32
Fizz
 34
Buzz
Fizz
 37
 38
Fizz
Buzz
 41
Fizz
 43
 44
FizzBuzz
 46
 47
Fizz
 49
Buzz
Fizz
 52
 53
Fizz
Buzz
 56
Fizz
 58
 59
FizzBuzz
 61
 62
Fizz
 64
Buzz
Fizz
 67
 68
Fizz
Buzz
 71
Fizz
 73
 74
FizzBuzz
 76
 77
Fizz
 79
Buzz
Fizz
 82
 83
Fizz
Buzz
 86
Fizz
 88
 89
FizzBuzz
 91
 92
Fizz
 94
Buzz
Fizz
 97
 98
Fizz
Buzz
stack12.v:309: $finish called at 6740 (1ns)




以上。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?