FPGA開発日記

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

RISC-V ISS Sv32, Sv39の実装

いまいち実装が進んでいないが、Sv32とSv39のISSへの実装しなおしが完了した。

Sv32とSv39については、前回の記事を参考にして欲しい。

msyksphinz.hatenablog.com

github.com

実装方法としては、まずはPTEを参照しながら上位の物理アドレスを生成していき、最後にPTEを参照しないアドレスを付加する。

  for (level = init_level-1; level >= 0; level--) {
    bool is_leaf_achieve = false;
    Byte_t p_pte[4] = {0};
    Addr_t va_vpn_i = static_cast<UWord_t>(vaddr) >> (12 + 10 * level) & 0x3ff;
    pte_addr += va_vpn_i * PTESIZE;
    pte_addr = ExtendSign(pte_addr, 31);

    LoadMemoryDebug (pte_addr, Size_Word, p_pte);
    memcpy (&pte_val, p_pte, 4);

...
    Addr_t mask = ((pte_val >> pte_idx[level]) & ((1 << pte_len[level])-1)) << ppn_idx[level];
    phy_addr |= ((pte_val >> pte_idx[level]) & ((1 << pte_len[level])-1)) << ppn_idx[level];
    pte_addr = ((pte_val >> pte_len[0]) & ((1 << (31-pte_len[0]+1))-1)) * PAGESIZE;
    // str << std::hex << " <Temporary Mask = " << std::hex << mask << ">\n";
    // str << std::hex << " <Temporary PhyAddr = " << std::hex << std::setw(16) << std::setfill('0') << phy_addr << ">\n";
    // DebugPrint ("%s", str.str().c_str());
    if (is_leaf_achieve) break;
  }

  // 下位のアドレスを接続する。
  for (level = level-1; level >= 0; level--) {
    phy_addr |= (vaddr >> vpn_idx[level]) & ((1 << vpn_len[level])-1) << ppn_idx[level];
  }

これで実装をしてみたのだが、テストパタンとしては途中でテーブル参照エラーを起こし、最後は無限ループになってしまった。結局最大サイクル数で停止してしまう。spikeでも同様のようだ。 これで本当にテストパタンはあっているのだろうか?