ALUで計算する命令のWB状態について、前回以下のように書きました。

「WB状態においては、ALUで計算する命令ならばレジスタファイルへの書き込みはイネーブルにされるので、EX状態で書き込み値を保存しておいたレジスタの値がすぐレジスタファイルに書き込まれます。その後、クロックのpositive edgeのタイミングで再びIF状態に遷移します。」

考えて見るとここは間違いでした。

レジスタファイルへの入力信号(書き込む値、書き込みイネーブル信号)はこの通り早々に設定されていますが、レジスタファイル自体がクロックのpositive edgeのタイミングで書き込みイネーブルならば書き込む制御をしているので、書き込み動作はWB状態の最後になります。

書き込みに必要な信号は、実際に書き込むタイミングより前であれば様々なタイミングでばらばらに準備が整っても構わないということですね。

週末にPOCOの4サイクル版のVerilogコードを読み直して動作を細かく考えて見ました。

4サイクル共、そのサイクルの最後のぎりぎりのところで動作していることに気付きました。例えば「IFにいる間に外部から命令をフェッチする」という風に漠然と理解していましたが、細かく考えるとIF状態にいる時のクロックのpositive edgeで外部からインストラクションレジスタirにフェッチし、なおかつ同edgeにて次のID状態に遷移するのだから、IF状態のほとんどの時間は1つ前の命令がirに入っているのであって、IF状態の最後の一瞬で次の命令が読み込まれます。漠然とした認識と比べると1段階ずれているような感じです。

これによりID状態では最初から次の命令がirに入っているので何の命令か正しくデコードできており、特にALUで計算する命令の場合はALUの3つの入力a,b,sにつながっているレジスタに、クロックのpositive edgeで命令から得られた値をセットし、なおかつ同edgeにて次のEX状態に遷移します。ALUはクロックは関係ない組み合わせ回路なので入力が確定すればそれだけで出力が決まりますが入力が変化した瞬間は不安定なので安定する次のクロックを待ちます。

EX状態にてクロックのpositive edgeのタイミングではALU出力が既に安定しており、その値をレジスタファイルへ書き込む値を保存するレジスタに取り込み、なおかつ同edgeにて次のWB状態に遷移します。

WB状態においては、ALUで計算する命令ならばレジスタファイルへの書き込みはイネーブルにされるので、EX状態で書き込み値を保存しておいたレジスタの値がすぐレジスタファイルに書き込まれます。その後、クロックのpositive edgeのタイミングで再びIF状態に遷移します。

ALUで計算する命令の動作については納得できましたが、サブルーチンコール命令は戻りアドレスをレジスタファイルに保存し、かつpcを書き換えますがそれをEX状態で行うVerilogコードになっています。ここが今一つ納得できていません。間違っているとも思いませんがID状態でやるか、ID状態とEX状態で分業しても良い気がしています。シミュレーションで確認しないといけないと思うのですが、いつできるかなあ。。
cdがシェルのビルトインコマンドで無いといけない理由が理解できました。
Chapter 0 はこれで終了です。

Code: File system

・chdirシステムコールにより、プロセスのカレントディレクトリを変更。
・openシステムコールでデータファイル、mkdirシステムコールでディレクトリ、mknodシステムコールでデバイスファイルを作る。
・fstatでファイルの情報を得る。
・linkシステムコールでファイルに別の名前をつけるとリンクカウントが+1される。
・unlinkシステムコールでファイルの名前を削除するとリンクカウントが-1される。
・リンクカウントが0になりファイルディスクリプタへの参照が無くなるとinodeとディスク領域が開放される。よって、テンポラリファイルをopenした直後にunlinkしておけば、プロセス終了時にテンポラリファイルは自動的に削除される。
・ファイルシステム操作コマンドのmkdir,ln,rm等はユーザーレベルのプログラムとして実装されているが、cdだけはシェルのビルトインコマンドになっている。そうでないとcdすると子プロセスが生成され、子プロセスのカレントディレクトリを変更した後に親プロセスに戻っても親プロセスのディレクトリは変更されていないことになるから。