CPU実験室

誰も見向きもしない古いCPUをいじって動かしてみようというプロジェクトです

クロック立上り時間

プログラムカウンタの最下位4ビット:Q0~Q3はうまい具合にCPLD基板上のLEDモニタに接続されているのでクロックを1Hzくらいまで落としてカウント値の遷移を目視で観察してみました。

すると

0-1-2-3-4-5-6-7-8-9-A-B-C-D-E-F-1-2-3-4-5-・・・

という具合でFまで行って桁上げするとき0を経由せずいきなり1になってしまっていてこれではアドレス0x10にあるコードがスキップされてしまうわけです。はじめはVHDLによるバイナリカウンタの記述に問題があるのかと疑いましたが、ここは教科書的な記述通りで問題を含みようがなく、ふと思いついてクロック源を自身のMC14500ボードからCPLD基板上にあるテストクロックに差し替えたらなんと正常にカウントします。

 

両者は何が違うのか・・

まず.MC14500ボード自前のクロックです。クロックに割れがあるのではないかと立上りエッジを拡大していますが立ち上がりに約200nsかかっていることがわかります

f:id:O3I:20210328195235j:plain

 

一方、CPLD基板上の米粒PICによるテストクロック源です。時間軸が異なりますが立ち上がりが約9ns、実に20倍以上の速度です。

f:id:O3I:20210328195255j:plain

 

どうもこれはMC14500ボード上で発生した立上り時間がかかりすぎるクロックを入力されたCPLDのカウンタが誤動作しているようです。

この自前クロックはMC14500チップ上にあるCR発振器用のインバータを介して出力されます。このインバータはアナログ的な動作をするためバッファを持たないUBタイプでゲインが低く、しかも元々が古い低速CMOSロジックの4000/4500シリーズ、遅いのはしかたがありません。

f:id:O3I:20210328203201j:plain

これを受けるロジック側では立上り立下りがゆっくりだと閾値を通過する時間が長くノイズでバタついたり、中途半端なレベルでCMOS出力のハイサイドとローサイド両方のFETがONしてしまうと貫通電流で電源電圧まで変動させてしまうおそれがあるらしいです。今回、特にF→0とか同時に多数のビットが変化するときに影響が出たのかもしれません。

 

MAX7000Sの規格を見てみると実際、立上り立下り時間とも40ns以下と明記されていました。

安易に古いロジックと新しいロジックを混在させるのは危ないってことですね。

f:id:O3I:20210328202124j:plain

プログラムループ

クロック同期プリセットができる12bitカウンタをEPM7064に焼き込み、以下のテストプログラムを実行させてみました。LEDを点灯、消灯をLED0~LED7に順番に行うので光が流れるように見えます。

f:id:O3I:20210327165918j:plain

プリセットがクロック非同期だと飛び先アドレスにはNOP+実効アドレスのマシンコードを置かないと異常動作しましたが、今回の修正でアドレス004のLOOPラベル行にそのような細工をしなくても問題なくなりました。

ところがここで新たな問題が発覚しました。クロックを1kHzくらいに設定しこのプログラムを実行させるとLED0~LED7がすべて高速点滅するのですべてがボーッと点灯しているように見えるはずですが、やってみると以下のようにLED6に相当するLEDだけが点灯していません。

 

f:id:O3I:20210327165931j:plain

最初、LEDの球切れか出力ラッチのポート破損かと思ったのですが、LED6のみをターゲットに絞りアクセスすると点灯するため、ハード的な故障ではありません。

いろいろ試しているうちソースコードのアドレス010にある以下の命令が無視されていてそのLEDが点灯指示されていないことがわかりました。

 

f:id:O3I:20210327172152j:plain

これがどんな命令であろうがアドレス010にあるとスルーされてしまうようです。

なんか経験したことがないトラブルです

プログラムロード

プログラムロード時には非同期プリセットをPICで叩くことでメモリへの展開ができるようになりました。なんですが、今度メモリに展開されたコードをダンプ機能で見てみると、なんか変なところがあります。

以下の出力はPIC上のモニタの中にデバッグルーチンを組込み、強制的に1番地に”0x1234”という1ワードを書いてダンプしてみた状態です。

1番地にコードが確かに書かれましたがその値は”0x1214”。そしてなぜか書き込みをしていない33番地にも同じワードがイメージで現れています。

 

f:id:O3I:20210322172033j:plain

そのあと、意味のあるプログラムコードを21ワード転送していますが、その後のダンプでは0~20番地に書かれたもののそっくりコピーが32~52番地にもあるように見えます。

0x12340x1214になる・・ということは16bitデータのうち、D5ビットが0になるようにマスクがかかっているといえます。またコントローラのPICが出力するバスはデータとアドレスを兼用しているので、アドレス的に見るとD5が常に0だと0~31と32~63番地は等価になってしまう(つまり同じものが見えてしまう)、ということです。

こりゃまたD5ラインにハンダの浮きがあって接触不良だろうとムキになってチェックしたのですが問題なし。あらためてPIC18F4550のマニュアルをみてみました。

 

D5ラインにアサインしているRB5ピンの機能は・・・

f:id:O3I:20210322172052j:plain

お? 低電圧プログラミング時のPGMピン機能もあるようです。で、コンフィグレーションを見てみるとなんとLVPビットがONになってました。ONだと他の機能はすべて無効化されるとあります。

f:id:O3I:20210322172122j:plain

これではRB5ピンは汎用入出力ピンとして機能しません。

これってHiTec-Cからxc8への移植の時に仕込んだのかと思ったら、最初から間違っていたみたいです。なんですがプログラム長が32ワード以下、コードで見た場合のD5は実効アドレスのD5なので使用するデータのサイズも32ワード以下なら全く動作に問題ないわけで、完全に見落としです。LVPビットをOFFに設定してうまくいきました。

ロジック変更

コントローラのPICからプログラムメモリにコードを書き込む場合、

①PICから12bit幅でアドレスを出力

②プログラムカウンタのPE(プリセット)端子をドライブしてアドレスをロード

③PICから16bit幅でインストラクション(4bit)+実効アドレス(12bit)を出力

④プログラムメモリの/WR端子をドライブしてメモリ書込み

の手順をとります

今回、プログラムカウンタをクロック同期プリセットにすると②のとき同時にCLK端子をドライブしなければならないのですが、現状回路を見るとどうみてもPICとCLK端子は直結されていません。

f:id:O3I:20210322141043j:plain

MC14500のリセットを解除してやるとX1X2へ入力したクロックが現れますが、今度はそれと同時にプログラムメモリの/OEが開いてしまい、メモリへの書き込みができなくなってしまします。

ここは本来ベースの回路を修正すればいいのですが既存のボードには手を入れず動態保存しておきたいのでCPLDのロジックを一部変更。

非同期プリセットAPEと同期プリセットSPEを分けてしまい、プログラム書き込み時はAPE、プログラム実行時はSPEを使うようにします

f:id:O3I:20210322141059j:plain

 

満身創痍

MC14500ボードにはバスに介入してICE的な動作をするコントローラPIC18F4550が載ってます。ホストからのプログラム転送、メモリへの展開も担っていますが今回プログラムカウンタをクロック同期にするため、このメモリアクセス部分の変更が必要です

 

このプログラムを最初に書いたのが5年以上前で当時の統合環境はMPLABのver不明、コンパイラHITEC-CのPICC18 Ver9.66でした。今回、現行環境MPLABX IDE5.45へツールチェインとしてPICC18を導入。とりあえず同じソースがコンパイルできるか試しました。ちょこちょこ環境依存のところを修正しながらリトライしたらなんとかビルドは通りバイナリができたのですがボードにダウンロードしたら全く動きません。どこかで何かやっちゃったみたいです。

これはもう新たにプロジェクトを起こしてコンパイラXC8 Ver2.30で作り直すしかありません。

もっともHiTec-Cxc8の前身なのでレジスタ表記などは可搬性があります。主な修正はConfigurationビットの記述とPICC18に付属していた周辺ライブラリを使ったコーディング:

f:id:O3I:20210319131041j:plain

これをレジスタ直叩きに変更するくらいです

f:id:O3I:20210319131057j:plain

 

何気なく始めた改造ですがだんだん大事になってきました。

ボードもいろいろなケーブルにつながれて重篤患者のあり様です。

 

f:id:O3I:20210319131118j:plain

 

カウンタ換装

 

MC14500ボード上のプログラムカウンタ跡地にアダプタ基板を差し、そのピンソケットからCPLDデバッグ基板のピンヘッダにジャンパ線を飛ばして両者を接続しました。

データ出力12本、プリセット入力12本、RESET信号、LOAD信号、電源2本でCPLDはワイヤのジャングルの中に埋もれています。

f:id:O3I:20210315220833j:plain

もともとMC14500ボード上の3個のMC14516の機能をそっくり外付け基板に移植しただけなんですが見た目が大げさすぎです。

ともあれ現状機能は満たしているはずなので今まで動いていたバイナリを転送したのですが案の定うんともすうとも動きません。というかプログラムメモリにコードが転送できていません。

 

・・とこれは意外に単純なミスで、システムコントローラPIC18F4550MC14516の非同期プリセット機能を使ってコード転送していたためでした。まずはカウンタを完全にMC14516とコンパチにするためにリセット、プリセットをクロック非同期にしました。

 

VHDLではprocess文のセンシテビティリストにRESET,LOADを追加しています

f:id:O3I:20210315220856j:plain

 

これをコンパイル、フィッテイングさせると

Total macrocells 12 / 64 ( 19 % )

Total pins 31 / 36 ( 86 % )

12ビットカウンタなので使用マクロセルはきっかり12個なのはいいですが使用ピン数はギリギリです、

f:id:O3I:20210315221234j:plain

 

ところでCPLDのピンアサインをプランナーでD0..11、Q0..11のようにきれいに並べようとするとフィッティングで失敗します。マクロセルとの接続関係で制約があるのでしょうが、うっかり決め打ちしたPLCC変換基板を発注しなくてほんとう良かったです。

 

さてこれでテストプログラムを転送できるようになり、実行も正常動作しています。

ただこれはやっと既存の動きができるようになっただけでこれをベースにカウンタの機能追加をしなければなりません

 

f:id:O3I:20210315220805j:plain

 

 

 

 

 

アダプタ完成

MC14516の跡地に挿すアダプタ基板が完成しました。12ビットバイナリカウンタの信号線をピンヘッダに取り出すだけなんですがこれだけつくるのに丸三日。疲労困憊しました。

f:id:O3I:20210313130200j:plain

 

1..27mmピッチのユニバーサル基板へのはんだ付けはほんと目がチカチカしてきます。基板を1000円くらいで外注すれば、コネクタ取付けだけで十数分で完成するものなんですけど。CPLDの開発が完了すれば不要になり、他には使い道もないものが一度に10枚もできてしまうのはあまりにもったいないのでしかたないです。

 

f:id:O3I:20210313130225j:plain