バス配線開始
今週の平日は大して進められませんでしたが、リセット・クロック回路を片付けてついにバス配線に手をつけました。土日でROMの動作確認までは進めたい。
ラッピングワイヤのはんだ付け方法にずっと悩んでたところ、ここでスライド法なるやり方を知って実践中です。合理的で性に合ってる感じ。ワイヤは OK Industries がいろいろな所でお勧めされているので自分でも買ってみたんですが、手持ちのストリッパじゃスライドできません。Engineer の PA-14 とこのカイナーワイヤーの組み合わせで上手くいってます。まぁ下手なりにですけどね。写真のバス配線でもさっそくショートしているところがあって、1本貼り直しました。
チップ抵抗、現る
TD4のROMユニットに普通のカーボン抵抗を配置する余裕がないので色々検討した結果、「チップ抵抗の手はんだ付けに挑戦してみよう!」ということになりました。LEDの電流調整抵抗はCPUの動作に関係ないから裏面に実装しても構うめぇ。で、さっそく買ってきたんですが、
小さすぎでしょこんなん……
左が2012型(2mm×1.2mmの意味)で左が1608型の1kΩチップ抵抗です。
ネットでいくつかハウツーを読んだら1608までなら手はんだ余裕っすわーみたいなノリだったので「ほーん、いけそうやな」という気持ちで部品屋の引き出し開けたら「は?」ってなりました。
ステマ気味に写ってるのは電子工作まんが『ハルロック』です。面白いよ!
こちらを参考にしつつ試しにはんだ付けしてみると……
ほーん、いけそうやな
お手製ダイオードアレイ 改良版
以前作ったダイオードアレイの見た目が気になっていたので改良しました。
長めの足を順々に継いでいく形だったのを、このように1本の長い橋に間の短い足をくっつけるようにしてみる。
この体勢で下から順にはんだ付け。コテとはんだで接続部を挟むようにすると、はんだの表面張力でまっすぐくっついてくれます。
上が前回の、下が今回のバージョン。美しさの違いが一目瞭然です。
じゃけんこれを16個作りましょうね~。
ROMのユニットはこんな感じかな。LED用の抵抗もここに詰められると楽なんですが、1/4WはDIPスイッチに干渉します。1/6W(持ってない)でも厳しそうだけど…一応注文しとこう。
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ヶ月かかりそうだぞい……。
レジスタ&ALU試作(成功?)
完璧に仕上がったクロック回路をひっさげて、いざ失敗したレジスタ&ALU回路のデバッグへ赴かん!……って、あれ、一昨日から配線弄ってないのにちゃんと動いてますけど……。これは「なんとなく直っちゃった」というできれば避けたかった事態ですね。釈然としないままTD4の命令を一通り実行できることを確認(JNCだけ命令デコーダ絡みなのでパス)。
以下、気付いたことなど。
- レジスタの値がめちゃくちゃに変化する!という現象は単に、MOVE命令でImDataを0000にし忘れてただけの気がします。レジスタB→Aとデータをコピーする時にImDataが加算されてるのに気付かず「誤動作だ!」と早とちりしていたのですね。誤動作してるのは私の頭でした。
- Dレジスタのカウンタが動作してなかった現象は謎です。↑と同じようなミスだと考えると、DレジスタのLOADフラグをONにしてしまっていたか。ただImDataはともかくセレクタ信号ABとレジスタのLOADフラグは本の記述と指差し確認してたはずなんですが。スッキリしない……。
- 74HC161の出力ピンからLEDを直接ドライブしたために定格電流超えで誤動作 or IC破壊していた疑いは、無罪放免となりました。まず161は全部無事でした。ロード、カウント、リセットともに完全動作することを確認。また、↑の写真はトランジスタでLEDをドライブしてますが、全部161の出力に直接ぶらさげても正常動作しました
(定格を超えてるのは間違いないので長い目で見ればアウトでしょうが)。ちなみに単独の動作テスト時にICの差込み位置が1個ズレて200mAくらい流しちゃうウッカリを3度ほどやらかしましたが、それでも(今のところは)壊れてません。結構丈夫だね!- 【追記】74HC161のデータシートをよく見てみたら、1ピンあたりの定格電流(Iout)が±25mAで、全ピン合計(Icc)が±50mAということっぽい。それなら今回使ってる抵抗内蔵LEDを4本直接光らせても問題ではなさそうです(赤はギリギリかも)。
- すると失敗時に161を単独で動作確認して「クロック立ち下がりでも出力が変わる!」とか言ってたのが怪しい。今回、配線は弄ってないとしつつもそれはレジスタとALU部分で、クロック回路は前回作ったモジュールに入れ替えたのでここが原因だったのかなぁ。チャタリングが解消されてるか確認すると書きながら強くは疑っておらず、失敗時のクロック回路を早々にバラして新規に実験を始めてしまったのが悔やまれる。写真から配線を再現して波形確認して、という手順でもうちょっと原因究明できますが、そんな地味な作業で日曜日を終わらせたくないので平日に暇を見てやります。多分。
次は命令デコーダの試作です。