自作3進CPU

【自作三進CPU】Libra the Processor の仕様

投稿日:2024-11-25 更新日:

現在進行形で作成中の自作三進 CPU 、愛称を Libra the Processor としました。(以下省略して Libra と書きます)

名前の由来は天秤座の英名 Libra です。平衡三進数は英語では Balanced Ternary といいますが、 balance という単語は天秤という意味も持ちます。

このページでは実装の回路的な話はあまりせずに、プログラムを描いたりするうえで把握したい情報をまとめたいと思います。

アーキテクチャ

まずは Libra のアーキテクチャを簡単に説明します。 Libra は大きく分けて以下の 4 つのユニットから構成されます。

  • ステートユニット
  • レジスタユニット
  • ALUユニット
  • メモリユニット

そしてすべてのユニットが一つの大きなバスに接続される形となっています。なお、すべてをバスに接続する形を採用したのは、それぞれのユニットを基板を分けて作ったときに接続しやすいようにという実装上の理由です。

4つのユニットがバスに接続されている図

次にそれぞれのユニットに含まれるものについて説明します。

ステートユニット

ステートユニットは CPU の状態を管理するためのユニットです。 Libra はマルチサイクルプロセッサなので、各クロックにおいて命令のどの段階を実行しているかを state が表します。具体的な状態遷移についてはここでは省略します。

PC (プログラムカウンタ)は実行する命令のアドレスを表し、 SP (スタックポインタ)はスタックトップのアドレスを表します。どちらも幅は 5trit 、初期値は -121 (0t#####) です。

sign は演算命令を行った際にその結果の符号が記憶されるレジスタです。条件付きジャンプに使用します。幅は 1trit です。

レジスタユニット

Libra は 3 つの汎用レジスタを持ちます。 Imm は即値命令を実行する際にメモリから読みだした即値を格納するレジスタで、自由にアクセスすることはできません。

A, B, C の 3 つのレジスタのうち、 A レジスタは特殊なレジスタで基本的にどの演算もオペランドの片方は A レジスタとなります。アキュムレータに近いですが、書き込み先は B, C も選べるので微妙なところです。後述する ISA も併せて確認してください。

レジスタはすべて 5trit です。

ALUユニット

ALU ユニットは計算を行うユニットです。(ALUのUはUnitなのでALUユニットって表記は気持ち悪いですね。)記憶素子は持ちません。

ALU が実行できる演算は以下のとおりです。(すべて 5trit 幅)

  • ADD
  • SUB (NOT + ADD)
  • NOT
  • AND
  • OR
  • Shift Left (1trit)
  • Shift Right (1trit)

Shift Left の LST, Shift Right の MST には 0 が補充されます。

メモリユニット

Libra は命令メモリ、データメモリ、スタックと 3 つのメモリを持っています。アドレス空間はそれぞれ独立しています。

アドレス幅、データ幅ともに 5trit です。

データメモリの 121(0t11111) 番地は MMIO として使用する予定です。(変更の可能性あり)

ISA

Libra 用の命令セットを紹介します。 ISA についてはあまり練れていないので、 Libra the Processor 1 号機が動いた後には改良することも考えています。

4~0 の欄は機械語のコードです。どの命令も 1 ワードで表現しています。即値を使う命令は命令本体と即値で 2 ワードとなっています。

r, d は A, B, C のレジスタを表し、機械語では A: 1, B: 0, C: # に対応します。

形式はアセンブリの引数を表しています。

命令説明sign変更命令長サイクル数43210形式
ANDd = A AND r131r11dDR
ORd = A OR r131r1#dDR
ADDd = A + r131r01dDR
MOVd = r131r00dDR
SUBd = A – r131r0#dDR
LDd = MEM[r]131r#1dDR
CMPA – r 131r#0R
STMEM[r] = A131r##R
SLd = A << 113011dD
NOTd = NOT A13010dD
SRd = A >> 1 1301#dD
ANDId = A AND imm250011dDI
ORId = A OR imm25001#dDI
ADDId = A + imm250001dDI
MOVId = imm250000dDI
LDId = MEM[imm]2500#1dDI
CMPIA – imm2500#0I
STIMEM[imm] = A2500##I
PUSHSTACK[SP] = A; SP++150#1N
POPSP–; d = STACK[SP]140##dD
JPC = imm25#11L
JPif (sign == 1) PC = imm25#1#1L
JZif (sign == 0) PC = imm25#0#1L
JNif (sign == #) PC = imm25###1L
CALLPUSH(PC+1); PC = imm27#10L
RETPC = POP();14##0N
HALTプロセッサ停止13#####N

特徴、注意点としては以下のような点が挙げられるでしょうか。

  • Aレジスタをオペランドの片方として使う
  • 書き込み先は自由に選べる
  • ST, PUSHはAレジスタからしか保存できない
  • 分岐はCMP + JZ (JP/JN) で行う
  • スタックへのアクセスはPUSH/POP, CALL/RET で行う。特にSPは直接触れない
  • MOVでもsignが変わってしまう(設計ミス)
  • CMPは引き算の結果の符号だけ使うが、オーバーフロー、アンダーフローしたときも下位5tritの値で符号を判断するので注意(設計ミス)

まだ私自身もこの命令セットでプログラムをほとんど書いたことがないので使い勝手が分かりません…

アセンブリ

アセンブリのサンプルとして適当に書いたプログラムを載せておきます。 R 形式だけ例がありませんが、まあ分かるでしょってことで。

記述の特徴としては以下の点があります。

  • コメントは //
  • 即値は10進法または0tのプレフィックスをつけた平衡三進法で記述
  • 即値の範囲は-121~121 (0t##### ~ 0t11111)
  • N形式は引数なし
  • L形式はラベル名を引数にとる

ツール

Libra the Processor を他の人にも触ってほしいという気持ちから、ツールをウェブで動かせるように作ったのでぜひ遊んでみてください。

-自作3進CPU

執筆者:


  1. 骨付き29 より:

    数学の授業中に先生が「3進法で動いているコンピューターとかないかな」って呟いたのを聞いて、確かにと思い調べ始めました。電子工作やプログラミングなどはやっていないにわかですが、三進CPUとありとても興味を惹かれました。setunでは調べても大した情報が出てこなかったので、実在しないわけはないだろうと思い調べていた所きっちーさんのサイトに辿り着けました。平衡三進法の記事も読みましたが、nmosとpmosってなんだろうで躓いてしまったので勉強してから出直します(?)面白い取り組みだと思いました!

comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


関連記事

3進Dフリップフロップを作ってみた【自作3進CPU】

自作 3 進 CPU 計画の第  …

3値論理回路を作ってみた【自作3進CPU】

かねてより温めていた計画&#12 …