FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

2026-01-01から1年間の記事一覧

RISC-V OoO CPUを実装する (37. 選択時に依存命令を起こす)

前回、発行と実行の間にレジスタを1本入れた。 そこで1サイクル置き去りにしていたものがある。 wakeupがwritebackのままだったので、依存する2命令の間隔が1サイクルから2サイクルに広がっていた。 N A: 選択 N+1 A: 実行+wb B: wakeup N+2 A: PRF書き込み…

RISC-V OoO CPUを実装する (36. 発行と実行を分ける)

scariv_topがどのモジュール単体よりも遅い状態が続いていた。 モジュール fmax scariv_iq 206.8 MHz scariv_rob 100.3 MHz scariv_lsu 152.5 MHz scariv_top 51.6 MHz IQが命令を選んでからPRFに書き戻るまで、途中にレジスタが1本もない。 合成では縮まな…

RISC-V OoO CPUを実装する (35. ROBのペイロードを3つに分ける)

前回、enable付きフリップフロップをやめて合成の数字が測れるようになった。 残していたのはフリップフロップの出力側で、topのクリティカルパスの先頭にいる。 7.69 7.69 ^ u_iq.i_rob_head_..._dfrtp_1_Q_1/Q (sky130_fd_sc_hd__dfrtp_1) 論理に入る前に7…

半導体フロントエンド設計100本ノック (19) In-order Completion Queue

半導体フロントエンド設計100本ノック、第19問。 今回は、演算結果がout-of-orderで帰ってきても、投入した順番でretireするCompletion Queueを設計する。 Queueといっても、単に入ったものを順に出すFIFOとは少し違う。Allocationは順番どおりでも、Complet…

RISC-V OoO CPUを実装する (34. enable付きフリップフロップをやめる)

26回目で、合成の数字が信用できない状態を3つ直した。 そのとき1つ残して先に進んだものがある。 uop_tに1bit足すと、scariv_iqが8.3 nsから19.7 nsになる。 面積は1.6%しか増えていない。 数字が変更の2.4倍動くなら、それは測定ではない。 1セルで7.11 ns…

半導体フロントエンド設計100本ノック (19) In-order Completion Queue

半導体フロントエンド設計100本ノック、第19問。 今回は、演算結果がout-of-orderで帰ってきても、投入した順番でretireするCompletion Queueを設計する。 Queueといっても、単に入ったものを順に出すFIFOとは少し違う。Allocationは順番どおりでも、Complet…

RISC-V OoO CPUを実装する (33. EBREAKと、mtvalの修正)

前回は、デコーダのis_illegalが例外処理に使われていなかった問題を直した。そのとき、EBREAKにも同じ問題があることに気付いた。 デコーダはis_ebreakを立てているが、breakpoint例外を上げる経路がない。今回はこの経路を追加し、mtvalに何を格納するかを…

RISC-V OoO CPUを実装する (32. 未定義命令のトラップの実装)

前回、misalignedのmtvalをどこから取るか考えているときに別のものが出てきた。 デコーダが立てているillegalを、誰も読んでいない。 印は立っていた デコーダは知らないオペコードに対してちゃんと印を立てる。 o_uop.is_illegal = 1'b1; o_uop.cat = INST…

RISC-V OoO CPUを実装する (31. misalignedのtrap対応と、mtvalの実装)

前回はfence.iを実装し、rv64ui-pは53/54になった。最後に「境界をまたぐmisalignedアクセスを実装して、rv64ui-pを閉じる」と書いたが、今回は方針を変えることにした。 misalignedアクセスをハードウェアで処理する代わりに、例外を上げる。テストを通す作…

RISC-V OoO CPUを実装する (30. fence.iとメモリが2つあった話)

前回までで、rv64ui-pの54本のうち52本が通るようになった。 残っているのはfence_iとma_dataの2本。今回は、自己書き換えコードを扱うfence_iを調べていく。 テストが要求していること sh a0, 2f, t0 sh a1, 2f+2, t0 fence.i la a5, 2f jalr t1, a5, 0 命…

RISC-V OoO CPUを実装する (29. 波形を画像にする)

前回まででランダム命令列を流せるようになり、riscv-testsと合わせて検証の網が一通り張れた。 その過程で気付いたことが1つある。 波形を見ていない ここ最近の作業で、波形をほとんど見ていない。 参照ISSとの突合わせ、assertion、unit TBが、どこで何が…

RISC-V OoO CPUを実装する (28. 命令列を長くする)

前回でCSRとstoreが比較対象に入り、riscv-tests 52本が命令単位で一致するようになった。 1命令が何をしたかは、これで一通り見えるようになった。 残っているのは、その網をどれだけ長い命令列に当てるか、という別の軸になる。 流している命令が少ない rv…

RISC-V OoO CPUを実装する (27. 比較する対象を増やす)

合成側が一段落したので、参照ISSとの突合わせに戻る。 これまで比較していたのはpcと書き込みレジスタだけだった。 命令が何をしたかのうち、見えていない部分がかなりある。 storeがどこに何を書いたか CSRがどう変わったか trapしたのかしていないのか 今…

RISC-V OoO CPUを実装する (26. 合成の問題を解消する)

前回、合成フローをcoreに向けて周波数と面積を測り始めた。 その続きで、critical pathを追いかける回。 結論から書くと、追いかけるたびに「測っていたものが測りたいものではなかった」が出てきた。 3回続いたので、そのまま記録しておく。 合成できない…

RISC-V OoO CPUを実装する (25. 周波数と面積を測り始める)

参照ISSとの突合わせが一段落したので、今度は合成側を動かす。 周波数と面積を継続的に追える状態にしたい。 合成の枠組み自体は少し前に作ってあった。 Yosys、OpenSTA、SKY130の標準セル、モジュール別の合成スクリプト、baselineと回帰チェック。 ただし…

RISC-V OoO CPUを実装する (24. mretをコミット時に移す)

前回、参照ISSとの突合わせで3つの食い違いが出た。 2つは片付いていて、残っていたのがmretだった。 今回はそれを直して、riscv-testsが命令単位で一致するところまで行く。 何が起きていたか CSR unitはmretが発行された時点でリダイレクトとフラッシュを…

RISC-V OoO CPUを実装する (23. 突合わせで最初に出た3つの食い違い)

前回で参照ISSとの命令単位の比較が動くようになった。 riscv-testsは52/54で通っている状態だが、比較を走らせると起動シーケンスすら抜けられない。 今回は、そこで出た3つの食い違いの話。 1つ目: 未実装CSRへのアクセスでtrapしていない 最初に止まった…

RISC-V OoO CPUを実装する (22. 参照ISSをDPI-Cで繋ぐ)

前回で参照ISSを動かす環境を作ったので、今回はそれをDPI-C経由でTBに繋ぐ。 実装そのものの回で、繋いだ結果出てきた食い違いは次回。 何を比較するか RTLがretireした命令1つにつき、ISSを1命令進めて突き合わせる。 比較するのは、pcと、書き込んだレジ…

RISC-V OoO CPUを実装する (21. 整形、assertion、参照ISSのコンテナ化)

前回で例外情報をレジスタ1個に集約し、riscv-testsは52/54で止まっている。 残り2本は機能が未実装なので、いったん検証側の整備に回った回。 RTL全体の整形、store経路へのassertion追加、参照ISSを動かすための環境作りの3つ。 RTL全体を自作フォーマッタ…

EmacsのSystemVerilog環境を自作する (2. lintとformatter、renameと設計階層browser)

msyksphinz.hatenablog.com 前回、Emacs Lispでlexerとparserを書き、その上にhighlightとindentを載せてPULPのaxiとcommon_cells (225 file / 314 design unit) に対してparse error 0件まで持っていった。 今回はその構文木の上に載せた残り — lint、bit幅…

EmacsのSystemVerilog環境を自作する (1. lexerとparser、highlightとindent)

RTLを書くときはverilog-modeを使ってきたが、indentが合わない、自分でtypedefした型に色が付かない、書き間違えてもVerilatorを回すまで気付かない、という不満が溜まっていた。 今回はEmacs Lispだけでlexerとparserを書き、その上にhighlightとindentを…

RISC-V OoO CPUを実装する (20. link addressの落とし穴と、例外レジスタへの集約)

前回はECALLのtrapを入れてriscv-testsの判定を正式化し、メモリ命令まわりを直して49/54まで進めた。 今回は残りのjump系を片付けて52/54にし、検証まわりの整理をしたあと、例外情報をROBのentryから1個のレジスタに集約する作業に入る。 jalで止まる: lin…

RISC-V OoO CPUを実装する (19. ECALL trapとメモリ命令まわりの修正)

前回はriscv-testsのbugを順に潰して、rv64ui-p-addがpassに到達するところまで進めた。 今回はECALLのtrapを実装してPASS/FAILを正式に判定できるようにし、そこから見えたメモリ命令まわりのbugを直す。 結果は43/54から49/54になった。 ECALLのtrap riscv…

RISC-V OoO CPUを実装する (18. riscv-testsで見つかったbugの修正記録)

前回、riscv-testsの実行環境を作った直後にrv64ui-p-addがfree listのdeadlockで止まった。 今回はその修正から始めて、rv64ui-p-addがpassに到達するまでに順に見つかったbugの記録。 結果として、free list、RAT、IQ、ROB、CSR flushの各所で合計9件のbug…

RISC-V OoO CPUを実装する (17. riscv-tests実行環境の構築)

全モジュールの統合とbranch redirectまで動いたので、いよいよ実命令test suiteを流す環境を作る。 目標はmake riscv-testsの一発で、riscv-testsのrv64ui-p-*全テストをbuildからPASS/FAIL集計まで通すこと。 今回はRTLではなくinfrastructureの話。 riscv…

RISC-V OoO CPUを実装する (16. Branch redirectと統合バグの修正記録)

Commit traceの出口ができたので、riscv-testsに進む前にbacklogに積んでいた2件、AUIPCのpc muxとbranch redirect (taken branchでのpipeline squash) を実装した。 設計は「retire時にtrapと同じ流儀で全flushする」という単純な形だが、統合テストを回し…

RISC-V OoO CPUを実装する (15. Commit slot expose: 実機コスト0のDIFFTEST hook)

前回でIQ age matrix入れて4命令が完走できる状態になった。 次のステップは「実行traceを外に出す」機構。retire (commit) 時の (pc, rd_addr, rd_data) をtop moduleのportとして拾えるようにして、reference ISS (spike / whisper) とco-simulationで状態…

RISC-V OoO CPUを実装する (14. IQ age matrix: 古い命令を絶対に追い越させない)

前回のtop moduleでpipelineが一通り繋がったが、smoke testの結果2命令retireで止まって「deadlock」していた。 原因はIQのpriorityが「physical entry indexのLSB」で決まっていて、free slotに埋まった若い命令が古い命令を追い越して発行され、in-order …

RISC-V OoO CPUを実装する (13. Top module: 配線とIQ deadlockの発見)

CSRまで単体moduleが揃ったので、全部を1本のtop moduleに繋いで実命令を流すフェーズに入った。 Fetch → Decode → Rename → Dispatch → ROB → IQ → EX (ALU/BRU/LSU/CSR) → WB → Retireのloopを閉じるのに、interfaceの型合わせ・PRF read glue・redirect f…

RISC-V OoO CPUを実装する (12. CSR + Trap: mstatus struct、WARL、trap fsm)

LSUまで一通りEXユニットが揃ったので、次はtrap pathを閉じるためのCSR unitを組んだ。 現段階のスコープは「M-modeのみ、8 CSR、CSR read/write 6命令、ECALL/EBREAK/MRETによるtrap起動」の最小構成。 interrupt (mie/mip/mideleg) やU/S mode、CSR field…