編集履歴一覧に戻る
mikecatのアイコン画像

mikecat が 2022年12月12日19時27分02秒 に編集

基板設計データのリンク忘れを修正

本文の変更

++[自作CPU Advent Calendar 2022](https://qiita.com/advent-calendar/2022/diycpu) 9日目++ [TD4の命令を実行できる自作CPU「Kageki」](https://elchika.com/article/9ac9fd67-86c5-4b1b-a355-4f662e8af794/)で電子サイコロを作ってみた。 # Dice Board |![Dice Board](https://camo.elchika.com/62d163ce7fda6fcfa73f26b3b14944188e505de7/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f34323336376365652d363839362d346364612d396134612d3433343133383638326635342f31356263386633332d663035312d343239312d383839302d623166326262323962306263/)|![Dice Board 回路図](https://camo.elchika.com/139b061ded7125a93418d97e2a78cf8bbabdbf24/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f34323336376365652d363839362d346364612d396134612d3433343133383638326635342f64663464336265642d333932332d346461332d383633332d323830653465353638663861/)| |---|---|

+

[基板設計データ](https://github.com/mikecat/hardware_cpu/releases/tag/20220404-boards-v1.0)

3ビットの入力を、以下のようにサイコロの目で表示する。 ``` 0     1     2     3 ○ ○  ○ ○  ● ○  ● ○ ○○○  ○●○  ○○○  ○●○ ○ ○  ○ ○  ○ ●  ○ ● 4     5     6     7 ● ●  ● ●  ● ●  ● ● ○○○  ○●○  ●○●  ●●● ● ●  ● ●  ● ●  ● ● ``` また、最上位ビットに1にすると、ブザー音を鳴らす。 ## 開発 まず、サイコロの目を以下のようにA~Gとおき、よく使われるサイコロの目である1~6について点灯させる位置をまとめる。 ``` A B CDE F G ``` 点灯させる位置を✓で表す。 |目|A|B|C|D|E|F|G| |:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:| |1||||✓||| |2|✓||||||✓| |3|✓|||✓|||✓| |4|✓|✓||||✓|✓| |5|✓|✓||✓||✓|✓| |6|✓|✓|✓||✓|✓|✓| すると、AとG、BとF、CとEが全く同じ点灯パターンであることがわかる。 そこで、これらをまとめる。 さらに、論理の観察がしやすいよう、目を2進数で表す。 |目|AG|BF|CE|D| |:-:|:-:|:-:|:-:|:-:| |001||||✓| |010|✓|||| |011|✓|||✓| |100|✓|✓||| |101|✓|✓||✓| |110|✓|✓|✓|| 目を $b_2b_1b_0$ と表す ($b_i$ はそれぞれのビットを表す) と、AG、BF、CE、Dはそれぞれ以下のように表せる。 * $AG = b_2 \lor b_1$ * $BF = b_2$ * $CE = b_2 \land b_1$ * $D = b_0$ これを用いると、0および7も整合性のとれた形で表現できる。 あとは、これを回路で表せばよい。 全てNANDゲートで表せるよう、以下の工夫をした。 * ANDは、負論理 (出力がLOWのとき点灯) のNANDで表現した。 * ORは、ドモルガンの法則 $b_2 \lor b_1 = \lnot (\lnot b_2 \land \lnot b_1)$ を用い、NANDゲート3個で表した。 さらに、入力をそのまま出力するBFおよびDについても、入力の仕様を統一するためNOT (NANDの一方の端子をVCCに固定) を挟み、負論理で点灯させるようにした。 残りのNANDゲートを用いて発振回路を組み、オン/オフの信号でブザーを鳴らせるようにした。 # 電子サイコロ ## 仕様 出力ポートの下位3ビットに現在の目(1~6)を出力する。(最初にサイコロを振る前は0を出力する) 入力ポートの最上位ビットが1の間、現在の目を切り替える。 現在の目を切り替えるとき、ブザー音出力用に、一旦出力ポートの最上位ビットを1にする。 ## プログラム ``` 場所 機械語 アセンブリ言語 ---------------------------------- 0 00100000 LOOP: IN A 1 00001000 ADD A, 1000 2 11100000 JNC LOOP 3 01011010 ADD B, 1010 4 11100111 JNC NOWRAP 5 01111001 MOV B, 1001 6 11111001 JMP WRAPPED 7 01011111 NOWRAP: ADD B, 1111 8 00000000 ADD A, 0000 9 10010000 WRAPPED: OUT B A 01011000 ADD B, 1000 B 10010000 OUT B C 11110000 JMP LOOP ``` 0番地~2番地で、キーが押されていない場合止める。 3番地で、目を進める。 進める前の目が6だった場合は、ここでキャリーが出るので、5番地で1に戻す。 進める前の目が6でなかった場合は、キャリーが出ず、7番地で1を引いて目を1進めた状態にする。 このどちらの場合でも、かかるステップ数が同じになるように調整している。 また、最上位ビットを立てる。 9番地で、新しい目を出力し、出力の最上位ビットを1にする。 A番地~C番地で、出力の最上位ビットを0にし、最初に戻る。 ## 実行結果 入力ポートに [Pmod BTN](https://digilent.com/shop/pmod-btn-4-user-pushbuttons/) モジュールを、出力ポートに Dice Board を接続して実行した。 @[youtube](https://www.youtube.com/watch?v=UwijP3c2Yh4) 100Hzのクロックで実行すると、目押しができる程度の速さになった。 1kHz程度のクロックで実行するのがよさそうである。