前回までで、L1キャッシュのモデルをISSに実装したのだが、L1 データキャッシュのシミュレーションしか実装していなかった。
L1キャッシュへのアクセスは命令フェッチの際に発生する。しかも今度はL1データキャッシュと違ってストアは発生しない。この方が楽だ。
L1キャッシュへのアクセス制御を一つの関数としてまとめる
void RiscvEnv::UpdateL1Icache (Addr_t addr) { if (FLAGS_sim_l1i) { Addr_t l1i_addr = MaskL1IAddr (addr); Addr_t l1i_entry_idx = MaskL1IIndex (addr); if (!m_icache_en[l1i_entry_idx]) { // L1I corresponding entry is empty m_icache_addr[l1i_entry_idx] = l1i_addr; m_icache_en [l1i_entry_idx] = true; DebugPrint ("[L1I:E:%08x,%03d] ", l1i_addr, l1i_entry_idx); } else { if (m_icache_addr[l1i_entry_idx] == l1i_addr) { // L1I corresponding entry is HIT DebugPrint ("[L1I:H:%08x,%03d] ", l1i_addr, l1i_entry_idx); } else { // L1I corresponding entry is MISS DebugPrint ("[L1I:R:%08x-->%08x,%03d] ", m_icache_addr[l1i_entry_idx], l1i_addr, l1i_entry_idx); m_icache_addr[l1i_entry_idx] = l1i_addr; } } } } void RiscvEnv::UpdateL1Dcache (Addr_t addr) { if (FLAGS_sim_l1d) { Addr_t l1d_addr = MaskL1DAddr (addr); Addr_t l1d_entry_idx = MaskL1DIndex (addr); if (!m_dcache_en[l1d_entry_idx]) { // L1D corresponding entry is empty m_dcache_addr[l1d_entry_idx] = l1d_addr; m_dcache_en [l1d_entry_idx] = true; DebugPrint ("[L1D:E:%08x,%03d]\n", l1d_addr, l1d_entry_idx); } else { if (m_dcache_addr[l1d_entry_idx] == l1d_addr) { // L1D corresponding entry is HIT DebugPrint ("[L1D:H:%08x,%03d]\n", l1d_addr, l1d_entry_idx); } else { // L1D corresponding entry is MISS DebugPrint ("[L1D:R:%08x-->%08x,%03d]\n", m_dcache_addr[l1d_entry_idx], l1d_addr, l1d_entry_idx); m_dcache_addr[l1d_entry_idx] = l1d_addr; } } } }
L1キャッシュの実装を追加した。命令フェッチの部分にICacheの実装を追加しておく。
MemResult EnvBase::FetchMemory (Addr_t addr, Word_t *data) { Byte_t byte_data[4]; Addr_t phy_pc = ConvertVirtualAddress (addr, MemAccType::FetchMemType); UpdateL1Icache (phy_pc); GetTrace()->SetTracePhyPC(phy_pc); MemResult result = m_memory->LoadMemWord (phy_pc, byte_data); memcpy (data, byte_data, 4); return result; }
オプションとして--sim_l1d, --sim_l1i
を用意しておく。--sim_l1i
を追加することで、以下のようにログが追加される。
[L1I:E:00000000,032] 0:M:MBar:[00000200][P00000200] 00008197 : auipc r03,0x00008 r03<=00008200 [L1I:H:00000000,032] 1:M:MBar:[00000204][P00000204] e1018193 : addi r03,r03,0xe10 r03=>00008200 r03<=00008010 [L1I:H:00000000,032] 2:M:MBar:[00000208][P00000208] 0000c117 : auipc r02,0x0000c r02<=0000c208 [L1I:H:00000000,032] 3:M:MBar:[0000020c][P0000020c] e0010113 : addi r02,r02,0xe00 r02=>0000c208 r02<=0000c008 [L1I:E:00000000,033] 4:M:MBar:[00000210][P00000210] 000000b3 : add r01,r00,r00 r00=>00000000 r00=>00000000 r01<=00000000 [L1I:H:00000000,033] 5:M:MBar:[00000214][P00000214] 00000233 : add r04,r00,r00 r00=>00000000 r00=>00000000 r04<=00000000 [L1I:H:00000000,033] 6:M:MBar:[00000218][P00000218] 000002b3 : add r05,r00,r00 r00=>00000000 r00=>00000000 r05<=00000000 [L1I:H:00000000,033] 7:M:MBar:[0000021c][P0000021c] 00000333 : add r06,r00,r00 r00=>00000000 r00=>00000000 r06<=00000000 ...