TD4ブレッドボード版できた!
命令デコーダがあっさり組めた勢いで、試作したモジュールを統合してブレッドボード版TD4を仕上げました。
動いてるところ: TD4 on ブレッドボード - YouTube
モジュールごとにきっちり動作確認してたおかげか難なく動いてくれました(まだ全部の命令を試してないのでバグはあるかもしれませんが)。超小規模とはいえコンピュータの動作を全部把握できてるというのは全能感ありますね。
ROM部分はさすがにブレッドボードで全部組むつもりはなかったので、Arduino Nano(の爆安互換品)でエミュレータを作っています。
こいつです。
大層なものでもないですがプログラムは以下の通り。
Uno とピンアサインが同じなら動くはず。
unsigned char rom[] = { // Aレジスタのスライドアニメーションを // Bレジスタが1クロック遅れで追いかけるプログラム B00110001, // MOV A,0001 B01000000, // MOV B,A B00110011, // MOV A,0011 B01000000, // MOV B,A B00110111, // MOV A,0111 B01000000, // MOV B,A B00111111, // MOV A,1111 B01000000, // MOV B,A B00111110, // MOV A,1110 B01000000, // MOV B,A B00111100, // MOV A,1100 B01000000, // MOV B,A B00111000, // MOV A,1000 B01000000, // MOV B,A B00110000, // MOV A,0000 B01000000, // MOV B,A }; void setup() { DDRB = DDRB | B00001111; DDRC = DDRC | B00001111; } void loop() { // アドレス入力 D5 D4 D3 D2 番ピン(右が最下位ビット) // データ出力 D11 D10 D9 D8 A3 A2 A1 A0 番ピン(右が最下位ビット) unsigned char addr = (PIND & B00111100)>>2; PORTC = (PORTC & B11110000) | (rom[addr] & B00001111); PORTB = (PORTB & B11110000) | ((rom[addr] & B11110000)>>4); }
4bitごとにデータ出力しているのでPOTC = ...
とPOTB = ...
の間にTD4のクロック立ち上がりが入るとたぶん誤動作します(TD4が)。まぁ、動作確認には問題ないでしょう。8bit同時に書き出すのはPORTD(ピンD0~D7)をフルに使うとできるけど、シリアル通信(D0とD1を使う)でのデバッグがし辛くなるのが面倒で横着。
追記
よく考えたらクロックが立ち上がる時はその時点でのプログラムカウンタ-1のアドレスの実行結果がレジスタまで来てるので、誤動作の話は心配するポイントが別ですね。クロックが立ち上がってカウンタが進み「次のクロック立ち上がり - 命令実行にかかる時間」までにROMからデータをロードできなければ誤動作、が正しいかな? それならTD4の動作速度から考えれば全く問題ないはず。これはADD A,0000; ADD B,0001
の繰り返しでROMを埋めて10Hzで丸1日放置、などでテストできそう。データバスに4bitずつ出力しているのが原因でオペコードと即値がちぐはぐになったら、レジスタ内容とプログラムカウンタの整合性が取れなくなるので。
さらに追記
ArduinoでROMをエミュレートする場合の注意点。ArduinoにUSBケーブルを挿すと「俺自身が電源になる事だ」モードに入るので、プログラム書き込み時にはTD4の回路から切り離しましょう。また、自動クロックモードで電源を入れるとArduinoの準備完了よりTD4の動作が先に始まって不定な命令コードが実行されます。これは手動クロックモードでTD4の電源を入れる or Arduinoが落ち着いてからTD4のリセットをかける、で対処してます(いいのかな? 一応、大電流が流れちゃう的なことは起きてないですが)。
さて、いよいよ本番の回路製作です。
まず配線図を起こすところから……これだけで1ヶ月かかりそうだぞい……。