コンピュータ基礎 入出力 天野 [email protected] I/O:入出力デバイス 一時的に データを保存するレジスタ、 制御用のレジスタを持つ CPU I/O ②外部との データ転送 制御方法 ①どのように 接続するか? 命令 メモリ データ メモリ I/O: CPUと外界のやりとりを制御 一時的にデータを蓄えるバッファ を持つハードウェアモジュール メモリマップトI/O 0000 CPU メモリ領域 I/O 8000 命令 メモリ データ メモリ I/O領域 データメモリと同じアドレス空間に I/Oのレジスタを割り付け、同じバス 上で接続する FFFF プログラムドI/O (Isolate I/O、Separate I/O) 0000 CPU 命令 メモリ データ メモリ I/O I/O領域 独立したバスを持つ I/O命令を持つ IN 0 OUT 1 など、、 メモリ領域 =独立した番号空間を 持つ FFFF メモリマップトI/O vs.プログラムドI/O • メモリマップドI/O – – – – I/Oとメモリを同一の命令、アドレス空間で扱える 命令の種類が減る ハードウェアが減る どのような構造のCPUでも使える • プログラムドI/O – メモリアドレス空間中にI/Oの虫食いができない – I/O中にメモリアクセスが可能 • Intel 86系はプログラムドI/Oでも実際にはメモリマッ プトI/Oで動いている I/Oデバイス コントロールレジスタ CPUのバス メモリに書くように 書き込む ステータスレジスタ 外界 データレジスタ メモリから読むのと 同じように読み出す データレジスタ: データの一時的な保存場所 コントロールレジスタ: I/Oに対する指示を覚えておく場所 ステータスレジスタ:I/Oの状態を覚えておく場所 データレジスタは双方向を同じ番地に割りあえてる場合もある コントロールレジスタとステータスレジスタは同じ番地を割り当てる場合もある 例:UART 8251 • パラレル/シリアル変換を行うI/O • モデム・端末インタフェースRS232C用 – 5bit-8bit単位でシリアル転送を行う – ボーレートはさほど高くない(最大でも10Mbps) • 現在でもIPとしてFPGA内で良く利用される シリアル転送フォーマット Start bit D0 D1 DN P Stop bit Start bit: 0にして開始を示す D0-DN: データ、5ビットから8ビットまで選択可能 P:パリティビット 偶数/奇数の選択可能 Stop bit: 1にして終了を示す。長さを選択可能 コントロールレジスタと ステータスレジスタ コントロールレジスタ EP PEN L2 L1 0 EP: Even Parity 1: Even 0: Odd PEN: Parity Enable 1: Enable ステータスレジスタ L2 0 0 1 1 L1 0 1 0 1 0 5bit 6bit 7bit 8bit Rx Tx RDYRDY TxRDY: 送信終了、送信バッファ(ダブルバッファ)に書き込み可能 RxRDY:受信終了、受信バッファから読み出し可能 ハンドシェイク(送信) I/O TxRDY フラグ 0 1 TxRDY=1ならば バッファ利用可能 書き込み ハンドシェイク(送信) I/O TxRDY フラグ 0 1 TxRDY=0の時には 次のデータを書き込む ことができない TxRDY=0ならば バッファ中にデータが存在 出力 ハンドシェイク(送信) I/O TxRDY フラグ 0 1 再び TxRDY=1ならば バッファ利用可能 書き込み 以降繰り返し ハンドシェイク(受信) RxRDY フラグ I/O 1 ステータスレジスタの RxRDY=1ならば バッファから読み出し 可能 1の時は次のデータの 書き込みができない フラグを使ってハザードを防ぐ • RAWハザード:Read After Writeハザード – 値が書き込まれるのを待って読み込む – 二重読みを防ぐ • WARハザード:Write After Readハザード – 値を読む前に書きこまれることがないようにする – 書き潰しを防ぐ • WAWハザード:Write After Writeハザード – これも書き潰しだが、WARがなければ普通大丈 夫 演習のI/Oインタフェース • ディスプレイを想定 – ASCIIコードを書き込むと出力される – ASCIIコード:英数字、記号用の8ビットコード • man asciiで表示されるのでLinux端末でやってみて! • 0x8000: – 書くとデータレジスタ – 読むとステータスレジスタ • 最下位ビットがTxRDY, 送信完了すると1になる 例題プログラム LDHI r0,#0x80 LOOP: LD r1,(r0) BEZ r1,LOOP LDI r1,#0x41 ST r1,(r0) → TxRDYが1になるまで ループ → ポーリング Busy Wait これでASCIIコード0x41:Aが出力される 演習1 データメモリの0番地から並んでいる5個のデー タをディスプレイから表示せよ。 さて、ここまでのI/O • 16ビットのデータのうちのほんの一部しか 使ってない – ステータスは1ビット – データでも8ビット → バイトアドレッシングの導入 • ビジーウェイトって、CPUは回ってばかりで馬 鹿みたい → 割り込みの導入 バイトアドレッシング 16ビット幅の場合 8ビット単位でアドレスを振る→今のCPUでは最も一般的な方法 LSB MSB 0 2 4 6 8 A C E 1 3 5 7 9 B D F Big Endian End POCOは こっち MSB LSB 1 3 5 7 9 B D F 0 2 4 6 8 A C E End Little Endian •統一されていない •データの順番が変わって大変なことになることも、、、 •最近は電源投入時にどちらかをセットする方法が一般化 バイトアドレッシング 32ビット幅の場合 MSB 0 4 8 C MSB LSB 1 5 9 D 2 6 A E Big Endian 3 7 B F 3 7 B F End 64ビットデータでも同様 LSB 2 6 A E Little Endian 1 5 9 D 0 4 8 C End LB Load Byte 00000 ddd sss 01100 LDと同様R型 LSB MSB 0 2 4 6 8 A C E 1 3 5 7 9 B D F 0 レジスタr0-r7 1 •符号拡張 End 8bitを16ビットに拡張する →CPU内では標準サイズで扱うのが RISCの原則 LBU Load Byte Unsigned 00000 ddd sss 01101 LSB MSB 0 2 4 6 8 A C E 1 3 5 7 9 B D F 0 レジスタr0-r7 1 •Zero拡張 End 8bitを16ビットに拡張する →CPU内では標準サイズで扱うのが RISCの原則 SB Store Byte 00000 ddd sss 01011 LSB MSB 0 2 4 6 8 A C E 1 3 5 7 9 B D F レジスタr0-r7 End 16ビットレジスタの下位8ビットを切って メモリに格納 → 上位8ビットは無視 プログラマの責任! SBUは存在しない ミスアラインメント LSB MSB 0 2 4 6 8 1 3 5 7 9 LD r0,(r1) 0 r1=0 1 レジスタr0-r7 偶数番地は問題ない LSB MSB 0 2 4 6 8 1 3 5 7 9 LD r0,(r1) r1=1 1 2 レジスタr0-r7 奇数番地だと2回アクセスしてくっつける必要がある →ミスアラインメント ミスアラインメントを許すか? • 許す利点: – メモリ利用効率が向上する – レガシーコードがコンパイルしなおさずに動く • 許す欠点: – 動作速度が遅くなる • メモリを2回アクセスしなければならない – ハードウェアが複雑になる • バイトをシフトしてくっつける必要がある • シフト操作自体はLBの時点で必要だが、、、 • 一般に命令では許さない。データではケースバイ ケース • POCOでは命令、データ共に許さないことにする 割り込み(Interrupt) • I/O側からCPUに対して割り込みを要求 • CPUはこれを受け付けると自動的にPCを割 り込み処理ルーチンの先頭に変更 • 戻り番地はどこかに保存 • 割り込み処理ルーチンを実行、終了後リター ン命令で元のルーチンに戻る → 元のルーチンは割り込みが起きたことがな かったかのように実行しなければならない 割り込みの実行 メインルーチン EI (Enable Interrupt) 割り込み処理ルーチン 割り込み 要求信号 RTI (Return from Interrupt) サブルーチンコールとの違いは、どこで呼ばれるか 分からない点にある 割り込み関係の命令 • EINT Enable Interrupt 00000 XXXXXX 01110 Xはdon’t care 割り込みを許可する • RTI Return from Interrupt 00000 XXXXXX 01111 PC ← IARにし、割り込みを許可する 割り込みの実現方法 • 割り込み処理のとび先番地 – 固定番地 POCOではff00とした • 割り込み処理ルーチンの先頭でどのI/Oが要求を出し たか調べる必要がある – テーブル引き • I/O毎に飛び先を変えることができる • 戻り番地の格納手法 – 特殊なレジスタ POCOではIAR(Interrupt Address Register) – ハードウェアスタック 割り込みの実装 VDD 割り込み要求線 オープンドレイン どれかがLならばL intreq CPU I/O I/O I/O オープンドレインの割り込み線を使って割り込み要求を 発生する。 割り込み処理ルーチンに飛ぶときに割り込みを禁止 → 割り込みが掛かり続けることを防止 CPUによる入力 CPU LB I/O SB メモリ LBで一度レジスタにとってきて SBでメモリにしまう CPUによる出力 CPU SB I/O LB メモリ LBで一度レジスタにとってきて SBでI/Oのデータレジスタへ出力 Direct Memory Access(DMA) CPU DMA要求 許可、 バスを開放 I/O I/Oがアドレスを指定し、 直接メモリとデータをやりとり メモリ 終了後はバスを開放し、 CPUに割り込みを掛ける CPUはDMAが掛かったことを 知らない 演習2 MSB 0x0 0x80 0x2 0x34 0x4 0x78 0x6 0xbc LSB 0x12 0x56 0x9a 0xde Big Endianのバイトアドレッシングを仮定する 以下のプログラムを実行した時のレジスタr1の値の変化を示せ LDI r0,#0 LB r1,(r0) LBU r1,(r0) LD r1,(r0) ADDI r0,#5 LB r1,(r0) LBU r1,(r0)
© Copyright 2024 ExpyDoc