RISC-VのRMW(Read Modify Write)命令を自作OoOコアに実装しようとしている。
基本的な機能の実装は完了したので、今度は依存する命令に対する発行制限などの機能を追加する。
実行中のRMW命令よりも若い命令は実行してはいけない。このためにパイプライン中にSTQ内の自分よりも古いRMW命令を検索するパスを追加し、もしRMW命令を発見すると実行停止、Oldestになるまで発行を中断する機能を追加した。
RMW命令が完了しても、まだ若い命令は実行してもいいわけではない。最終的にL1Dキャッシュの値が確定するのは、AMO演算が完了した後となる。したがってSTQ内とストアバッファ内にハザード検出パスを追加し、AMO演算が完了していない間は当該アドレスへの後続命令のアクセスがあるとフォワーディングを禁止する(実行を停止する)
ストアバッファは先頭の1エントリだけAMO演算をサポートすればいいと思っていたが、ストアバッファのエントリ確保はそこまで柔軟にしていなかった。したがってステートマシン自体はすべてのストアバッファエントリでAMO演算をサポートし、AMO演算のためのユニットはストアバッファ内で共通とした。このためのアービトレーションパスが必要となるが、どっちにしろストアバッファ内にはAMO演算は1つしか存在しないはずなので単純なAND-ORで作りこんだ。
これにより、LR/SCを除いたriscv-testsのアトミック演算テストを全てPASSできるようになった。大きな進歩だ。
rv64ua-p-amoand_w : PASS rv64ua-p-amoadd_d : PASS rv64ua-p-amoor_w : PASS rv64ua-p-amoor_d : PASS rv64ua-p-amomin_w : PASS rv64ua-p-amoadd_w : PASS rv64ua-p-amoand_d : PASS rv64ua-p-amomaxu_w : PASS rv64ua-p-amomax_d : PASS rv64ua-p-amominu_d : PASS rv64ua-p-amomaxu_d : PASS rv64ua-p-amoswap_d : PASS rv64ua-p-amomin_d : PASS rv64ua-p-amominu_w : PASS rv64ua-p-amomax_w : PASS rv64ua-p-amoxor_d : PASS rv64ua-p-amoxor_w : PASS rv64ua-p-amoswap_w : PASS rv64ua-p-lrsc : UNKNOWN rv64ua-v-amoadd_d : PASS rv64ua-v-amoadd_w : PASS rv64ua-v-lrsc : ERROR rv64ua-v-amoswap_d : PASS rv64ua-v-amoxor_w : PASS rv64ua-v-amomin_w : PASS rv64ua-v-amomaxu_d : PASS rv64ua-v-amoswap_w : PASS rv64ua-v-amomaxu_w : PASS rv64ua-v-amoor_d : PASS rv64ua-v-amomax_d : PASS rv64ua-v-amomin_d : PASS rv64ua-v-amoxor_d : PASS rv64ua-v-amoand_w : PASS rv64ua-v-amoor_w : PASS rv64ua-v-amominu_d : PASS rv64ua-v-amoand_d : PASS rv64ua-v-amomax_w : PASS rv64ua-v-amominu_w : PASS