SSブログ
English Version

SuperSimpleController [OriginalCPU]

 標準ロジックICなどを使ってオリジナルCPUを検討してみました。

 FPGAなどで作った方が容易そうですが、限られた環境の中で考えてみるのが楽しそうだったからです。
(結構特殊なロジックICを使ったりするので海外手配の場合、時間がかかって進捗がイマイチです^^;)

 フェッチしたインストラクションの値からROMで実装したルックアップテーブルでコントロール信号を生成する予定で、この部分はCISCプロセッサのマイクロコードに対応します。言い換えれば機械語の処理を実現するために記述するメタ言語的なものになります。

 今後の検討で変更する可能性もありますが下図のような構成を考えています。

オリジナルCPU概要ブロック図


 まずはマイクロコードの実行部分の実験としてjump命令と制御信号出力のみの機能を搭載した簡易版のコントローラを作ってみました。
 今回は制御信号出力でLCDへの表示も行ってみました。最終的には制御信号出力によりCPU内のリソース制御を行うことでオリジナルCPUにする予定です。

 回路は下図のとおりで74AS867、74HC04、W27C512の3チップ構成で非常にシンプルな構成です。

超シンプルなコントローラー


 目視で動きが判るようにクロックを遅く設定していますが、数MHzでの動作も可能なのでこれだけでも何かの固定的な制御に使えそうですね。
 制御信号のMSB(D7)がlowの時にアドレスがD0..D6の値に設定されるようにすることでjump命令を実装しています。

 最初に下記の簡単なパターンをROMに書込み動作確認してみました。
 0008Hアドレスの00Hで先頭にjumpします。

テストデータ


 実際に動かしてみた時の波形が下図です。想定通り00Hでアドレスがクリされて先頭に戻っています。

テストデータ実行時の波形


 次にLCDを接続して文字を表示してみることにします。
 バイナリデータを直書きしてもいいのですが可読性を向上させるためにマクロアセンブラのマクロ機能を利用し、HEXファイルを生成しています。

 LCDの制御に関しては「PIC24FJの出力コンペアモジュールとLCD3V駆動の実験」の記事で書いた処理をマイクロコードに書き換えています。

LCD制御用マイクロコード
;+++++++++++++++++++++++++++++++++++ ; Super Simple Controller ; LCD display ; Ver 0.01 2020/06/01 by skyriver ;+++++++++++++++++++++++++++++++++++ LcdWrCmd macro cmd DB 11000000B or cmd DB 11100000B or cmd DB 11000000B or cmd ENDM LcdWrDat macro dat DB 11010000B or dat DB 11110000B or dat DB 11010000B or dat ENDM LcdWrDat8 macro dat LcdWrDat (dat/16) LcdWrDat (dat)and(0FH) ENDM Jump macro adr DB adr ENDM 0080 JP_bit EQU 80H ; 0:jmp 0020 E_bit EQU 20H ; E 1:enable 0010 RS_bit EQU 10H ; 0000' ASEG ORG 0 0000 CF DB 11001111B ; LcdWrCmd( $03 ); LcdWrCmd 3 0001 C3 + DB 11000000B or 3 0002 E3 + DB 11100000B or 3 0003 C3 + DB 11000000B or 3 ; LcdWait( 82 ); ; LcdWrCmd( $03 ); LcdWrCmd 3 0004 C3 + DB 11000000B or 3 0005 E3 + DB 11100000B or 3 0006 C3 + DB 11000000B or 3 ; LcdWait( 2 ); ; LcdWrCmd( $03 ); LcdWrCmd 3 0007 C3 + DB 11000000B or 3 0008 E3 + DB 11100000B or 3 0009 C3 + DB 11000000B or 3 ; LcdWrCmdWait( $02 ); LcdWrCmd 2 000A C2 + DB 11000000B or 2 000B E2 + DB 11100000B or 2 000C C2 + DB 11000000B or 2 ; LcdWrCmdWait8( $28 ); # set 4bit mode LcdWrCmd 02H 000D C2 + DB 11000000B or 02H 000E E2 + DB 11100000B or 02H 000F C2 + DB 11000000B or 02H LcdWrCmd 08H 0010 C8 + DB 11000000B or 08H 0011 E8 + DB 11100000B or 08H 0012 C8 + DB 11000000B or 08H ; LcdClear(); 0013 CLEAR: LcdWrCmd 00H 0013 C0 + DB 11000000B or 00H 0014 E0 + DB 11100000B or 00H 0015 C0 + DB 11000000B or 00H LcdWrCmd 01H 0016 C1 + DB 11000000B or 01H 0017 E1 + DB 11100000B or 01H 0018 C1 + DB 11000000B or 01H ; LcdWrCmdWait8( $06 ); # set entry mode,inc,non-shift LcdWrCmd 00H 0019 C0 + DB 11000000B or 00H 001A E0 + DB 11100000B or 00H 001B C0 + DB 11000000B or 00H LcdWrCmd 06H 001C C6 + DB 11000000B or 06H 001D E6 + DB 11100000B or 06H 001E C6 + DB 11000000B or 06H ; LcdWrCmdWait8( $0c ); # display on LcdWrCmd 00H 001F C0 + DB 11000000B or 00H 0020 E0 + DB 11100000B or 00H 0021 C0 + DB 11000000B or 00H LcdWrCmd 0CH 0022 CC + DB 11000000B or 0CH 0023 EC + DB 11100000B or 0CH 0024 CC + DB 11000000B or 0CH ; +++ write string +++ LcdWrDat8 'H' 0025 D4 + DB 11010000B or ('H'/16) 0026 F4 + DB 11110000B or ('H'/16) 0027 D4 + DB 11010000B or ('H'/16) 0028 D8 + DB 11010000B or ('H')and(0FH) 0029 F8 + DB 11110000B or ('H')and(0FH) 002A D8 + DB 11010000B or ('H')and(0FH) LcdWrDat8 'e' 002B D6 + DB 11010000B or ('e'/16) 002C F6 + DB 11110000B or ('e'/16) 002D D6 + DB 11010000B or ('e'/16) 002E D5 + DB 11010000B or ('e')and(0FH) 002F F5 + DB 11110000B or ('e')and(0FH) 0030 D5 + DB 11010000B or ('e')and(0FH) LcdWrDat8 'l' 0031 D6 + DB 11010000B or ('l'/16) 0032 F6 + DB 11110000B or ('l'/16) 0033 D6 + DB 11010000B or ('l'/16) 0034 DC + DB 11010000B or ('l')and(0FH) 0035 FC + DB 11110000B or ('l')and(0FH) 0036 DC + DB 11010000B or ('l')and(0FH) LcdWrDat8 'l' 0037 D6 + DB 11010000B or ('l'/16) 0038 F6 + DB 11110000B or ('l'/16) 0039 D6 + DB 11010000B or ('l'/16) 003A DC + DB 11010000B or ('l')and(0FH) 003B FC + DB 11110000B or ('l')and(0FH) 003C DC + DB 11010000B or ('l')and(0FH) LcdWrDat8 'o' 003D D6 + DB 11010000B or ('o'/16) 003E F6 + DB 11110000B or ('o'/16) 003F D6 + DB 11010000B or ('o'/16) 0040 DF + DB 11010000B or ('o')and(0FH) 0041 FF + DB 11110000B or ('o')and(0FH) 0042 DF + DB 11010000B or ('o')and(0FH) LcdWrDat8 '!' 0043 D2 + DB 11010000B or ('!'/16) 0044 F2 + DB 11110000B or ('!'/16) 0045 D2 + DB 11010000B or ('!'/16) 0046 D1 + DB 11010000B or ('!')and(0FH) 0047 F1 + DB 11110000B or ('!')and(0FH) 0048 D1 + DB 11010000B or ('!')and(0FH) ; +++ jmp to clear Jump CLEAR 0049 13 + DB CLEAR END Macros: JUMP LCDWRCMD LCDWRDAT LCDWRDAT8 Symbols: 0013 CLEAR 0020 E_BIT 0080 JP_BIT 0010 RS_BIT No Fatal error(s)


 電源オン直後の波形が下図です。信号名のカッコ内はLCD側の信号名称です。

LCD制御での電源ON直後の波形


 YouTubeに動作サンプルをアップしましたので貼っておきます。
 赤LEDがアドレスで緑LEDがデータです(上記の回路図にはLED部分は含まれていません)


https://www.youtube.com/watch?v=EuEsv856V10


[TOP] [ 前へ ] 連載記事 [ 次へ ]

nice!(0)  コメント(0) 
共通テーマ:趣味・カルチャー

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。