29 |
RISC-Vプロセッサの設計 (26) |
パイプライン動作において、そのサイクルが有効か無効かは重要な情報です。無効サイクルはパイプラインバブルとも呼ばれます。
そこで、本来PCパイプラインには不要ですが、制御信号パイプラインに必要な、Maybe型を用いてパイプラインを記述します。Maybe型は以下に示すようにtagged unionで定義され、validの場合には値を持ちinvalidの場合には値を持たない型です。
typedef union tagged {
void Invalid;
data_t Valid;
} Maybe #(type data_t) deriving (Eq, Bits);
以下に修正箇所を示します。
Processor.bsv
int型のFIFOを設けていたところをMaybe型のFIFOに修正します。int型のペイロードに対して1bitのvalid/invalidを表すtagを付加します。
FIFO#(Maybe#(int)) ifs <- mkFIFO;
FIFO#(Maybe#(int)) ids <- mkFIFO;
FIFO#(Maybe#(int)) exs <- mkFIFO;
FIFO#(Maybe#(int)) mas <- mkFIFO;
FIFO#(Maybe#(int)) wbs <- mkFIFO;
次に<IF>においてwaitが来たら上位のdeqと下位のenqを停止していましたが、制御信号の場合はwaitの時、下流にinvalidを流すように変更します。このinvalidはパイプラインバブルです。
// <IF>
rule if_stage;
let pc_if = ifs.first;
if (!if_wait) begin
ifs.deq; // !waitの場合はデキュー
$display (" pc_if = %04h", pc_if);
ids.enq (pc_if); // !waitの場合はその値を下流にエンキュー
end else begin
ids.enq (tagged Invalid); // waitの場合下流にinvalidを流す
end
endrule
コンパイルと起動コマンドは以下のとおりです。
$ bsc -u -sim Tb.bsv; bsc -sim -e mkTb -o mkTb.exe;
$ ./mkTb.exe -V;
$ gtkwave -A dump.vcd
以下はbsimシミュレーション波形です。Maybe型は33bitのデータでありMSBがvalid bitとなっています。 標準ではGtkwaveはMaybeのinvalidを認識せず赤色にならないため、手で赤色に修正しました。
以下はverilogシミュレーション波形です。verilogでも同様です。
bsimとverilogで全く同じ動作となっています。まとめとして、ステージ中にwaitが入る場合の処理は、
- 上位へはdeqをサイクル中で停止、するとFIFOがfullでとまる。ただしFIFOは1段。
- 下流へはデータパイプラインの場合はvalid bitは不要であり、値を保持
- 下流へは制御パイプラインの場合はinvalid(パイプラインバブル)を流す