CPU実験室

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

68030プロジェクト始動

ようやくPentiumに着手・・と言いたいところですがやはり64bitバスというのに怖気づいて結局32bitバスのMC68030に日和りました

ささっとブロック図書いてみました。

メインのMC68030にやっぱりこれは欠かせないFPU:MC68881を配しています。ブートROMは68kシリーズの特徴であるダイナミックバスサイジングを利用して8bit幅・・・これでデバッグ時ROMの抜き差しは1個ですむのがうれしい・・・一方ロードしたプログラムを実行させるSRAMエリアは32bit幅にしてあります

このほか周辺にパラレル82C55とシリアル85C30を置いて大体こんなものでよいでしょう

 

これらのパーツはたぶん手持ちがあるはず、と思っていたのですがいざ探してみるとなかなか見つからず。押入れをひっくり返してようやくキーとなるパーツが出てきました。親玉の68030は何かのジャンクボードから抜いたものですが50MHzの高クロック品です。一方68881は20MHz品でちょっと見劣りがしますがMPUとFPUは別クロックでもよかったような気がしていてここは要調査です

このとき一緒にPLCCのMC68882も出てきました。6888268881の改良品で同一クロックの68881より40%速いという主張もあります。しかも最大クロックが25MHzなので性能的にはこちらと組み合わせるのがベストですが金色のPGAが2個並ぶ図も捨て難い。性能を取るか見た目を取るか悩むところです

ミッシングリンク

DSP56001ボードはハードが完成、基本的なプログラムが動作したところで急速に熱が冷めてしまいどう応用するかはしばらく検討中です。

 

一方で早くもあらたなCPUボードを画策していて次のターゲットに狙いを付けています。

CPU各メーカは新しいアーキテクチャの製品を開発すると鳴り物入りで登場させ、それが社会に受け入れられるとアッパーコンパチを保ったままシリーズ化してきました。代表的なのはインテル8086に始まるシリーズで、いまだに「x86」という言葉があるように百位をインクリメントして命名していました。他メーカでも同じようなことをしていてxの値で仮に「第x世代」とするとこのような感じです

 

メーカ Prefix

第0

世代

第1

世代

第2

世代

第3

世代

第4

世代

第5

世代

第6

世代

Intel i 8086  80186 80286 80386 80486 P5  
Motorola MC 68000 68010 68020 68030 68040   68060
Texas TMS   32010 320C25 320C30 320C40 320C50  
AMD Am 29000     29030 29040 29050  
National NS 32032 32132  32232  32332   32532  

 

基本的に世代が進むごとにバス幅や機能が拡張されていきますが、単純に発表順であって中にはマイナーチェンジだったり過去のCPUコアに周辺を取り込んだだけだったりのもあります。だいたい初号機の第0世代を含む偶数世代は世間に絶賛をもって迎えられ、次の奇数世代はガッカリ・・といった評価はあるとかないとか・・

このようにシリーズ化しているとそこはコンプリートしたくなります。上の表で赤文字のCPUは制作実績がありますが、手持ちのもので次にやるとすると何度も候補として浮上してはお蔵入りとなっているpentiumか、68020と68040の間、長らくミッシングリンクになっている68030かと

 

ループバック

コーデックの基本的な操作はなんとかできるようになったのでやっとアナログ信号のループバックをやってみます

 

プログラムはフレーム同期のたびに更新される左右チャンネルのA/D結果をそのまま左右チャンネルのD/A出力に書き込む、コーディング上はRXバッファの2ワードをTXバッファにコピーしているだけです

 

ところでこのDSP56001ボードにはスペース的にアナログ入出力のジャックが乗らなかったのでフラットケーブルをφ3.5ジャックに変換するケーブルを作っておきました

 

アナログ入力にはラジオ音声、アナログ出力はモニタスピーカにつないでボード上でループバックプログラムを実行と・・・これはADSP2101でのやり方と全く同じです

音質は全く問題なし(一応16bitリニアPCM、fs=48kHzでDAT相当)、ノイズもほとんどありません

 

 


あとは1フレーム内での入力出力データコピーの間に演算処理を入れていくことになりますがどれほどの計算時間余裕があるかが問題になります

 

コーデック出力

アナログ折り返しテストは入力ソースが必要なため、先ずは出力テストのためDACに数値データを書き込み出力信号を観察してみることにしました

  前に書いたようにYデータ空間の0x0100~0x01FF番地には1周期のサインデータテーブルROMがあるのでこれをフレーム割込み毎に1ステップずつ出力させます

 

1周期のデータ数は256個、サンプリング周波数fsは48kHzのためサイン波の周波数は48000/256=187Hzで期待通り出力されました

 

このとき時間軸を引き延ばして1フレーム内でのフラグ状態を見てみると確かにフレーム周期48kHzですが実処理(単なるサインテーブル参照)でやはりフレーム内時間の50%以上を消費してしまっています。

デジタル信号処理によるフィルタの次数やエフェクトの複雑さはフレーム内でどれだけの演算ができるかにかかわるので処理遅すぎな気がしますがどうなんでしょうか

 

ところでサインデータテーブルとそのままのアドレスでXデータ空間に切り替えるとμ-law、A-lawの係数テーブルが引き当てられます。係数をそのままアナログ出力することは何の意味もありませんが、値をプロットしたグラフと同じ形が出てきます

 

 

コーデック通信

既存のサンプルプログラムを解析し、それをなぞってコーディングするのに苦戦していてなかなか進んでいません。データシートで理解した通りのコーディングがしてあればよいのですが、そうでないところも多々あり・・まあ往々にして自分の理解違いなんですが。

コーデックのデータモードで割込み都度にデータを送受信しますが送信、受信それぞれに8バイト4ワードのバッファを用意しておきます

1サンプリング間隔=1フレームは8タイムスロットに分割され、16ビットステレオモードのときは以下のように順にデータが転送されるようです


コーデックによるデータバッファの更新は割込みで行われるので常時受信バッファの参照、送信バッファへの書込みが直接できます。

モトローラ製評価ボードのサンプルプログラムでは無限ループの中でSSISRレジスタでフレーム同期をチェックして受信バッファの内容を送信バッファにコピーするという処理をしているので、アナログ側から見るとライン入力した信号がそのままライン出力に折り返されてくる動作になります

 

このコピー処理の始まりと終わりにパラレル出力ポートをトグルしてみると確かに周期的にON/OFFしていることがわかります。ただその間隔は平均では設定したサンプリング周波数通りの48kHz’(1/48ms)程度なのですがフレーム間隔が1/44ms~1/54msくらいでばらつくのと単なるバッファ間コピーにフレーム時間の半分くらいも要しているのが何か変です

 

コーデック接続(3)

割込み処理のお膳立てができたのでコーデックの初期化をやっていきます。やはりマニュアルを読んだだけではサッパリなのでサンプルコードを引っぱて来ています・・ところが汎用出力で叩くRESETとC/Dの結線を間違えていてサンプルコードそのままでは動かないことも発覚・・手直ししたりコードを整理したりして多少理解が進みました。

 

それで、コーデックの初期化ですがその前にDSP側SSI同期シリアルの初期化をしています。転送レート、ビット数、フレーム当たりのワード数を設定してからコーデックをコントロールモードでリセット解除

送信バッファにコーデックのコントロールワード:量子化ビット数・サンプリング周波数やステレオ/モノラルなど最初に1回だけやればよい設定をセットし、割込みマスク解除、4ワードが転送されるのを待ちます

つづいてコーデックをデータモードに切り替え、今度は送信バッファに4個のデータワードをセットしておきます。これ以降サンプリング周波数の1フレームごとにこの4ワードがコーデックに送信されることになります

 

コーデック接続(2)

ひと月以上放置してしまいましたが56kボードいじりをやっと再開。やることはコーデックの接続からでした。

参考資料としてそのものずばりのDSP56002EVMのマニュアルはあるのですがかんじんのコーデック部分は既製のサブルーチンとして中身までは説明に触れてなくサンプルコードのコメント見ながら読み解いてます

まず判ったのは

・コーデックとの通信はSSI同期シリアル通信
・コーデックはマスタモードで動作し、起動のトリガ・通信の主導権はコーデック側にある

ということでこれは前にいじったADSP2101とAD1847の関係と同じです。

ただしADSP2Kではコーデック側との送受信データをメモリ上に置いておけば然るべきタイミングでハードが自動的にSSIを介してコーデックとやり取りしてくれたのに対し、DSP56KではSSIの送受信割込みのタイミングでソフト的にSSIにアクセスしてデータを授受しなければならないようです

フレーム内で全てを完了させ遅れは許されないリアルタイムDSP処理においてソフトウェアのオーバーヘッドが大きいのは如何なものかと思いますがそういう作りならばしかたありません。

まずはプログラム空間0番地から始まる割込みベクタテーブルを記述しておきます。これはモニタROMをE000番地以降に移しユーザプログラムを0番地から配置できるのでモニタ環境下でも実行可能になったものです

割込ベクタ32個のうち7~10番(0x000C~0x0012)がSSIの送受信に関係します

次にコーデックとやりとりするデータバッファをXデータ空間に準備。1フレームに8タイムスロットあるので送受信とも8バイト(4ワード)必要です

 

さて次はSSIとこのデータバッファ間でデータをやり取りする割込みサービスルーチンです。送受信それぞれフレームシンクが来たらバッファのポインタをリセット、それ以外の割込みならばポインタを進めるという作りは理解できるのですが・・

送信割込みでフレームシンクした時のリセットポインタが+0でなくて+1なのが謎です。ここらへんはサンプルコードそのままの受け売りなのでとりあえずこのまま行きます