[sim] added icache simulator (disabled by default)
authorAndrew Waterman <waterman@s144.Millennium.Berkeley.EDU>
Fri, 15 Apr 2011 21:32:54 +0000 (14:32 -0700)
committerAndrew Waterman <waterman@s144.Millennium.Berkeley.EDU>
Fri, 15 Apr 2011 21:33:12 +0000 (14:33 -0700)
13 files changed:
config.h.in
configure
riscv/applink.cc
riscv/icsim.cc [new file with mode: 0644]
riscv/icsim.h [new file with mode: 0644]
riscv/mmu.h
riscv/processor.cc
riscv/processor.h
riscv/riscv-isa-run.cc
riscv/riscv.ac
riscv/riscv.mk.in
riscv/sim.cc
riscv/sim.h

index e59281002c450cc5c6c43bd398972016d709b66c..cf21aff58e97c497ee7cc96ffbc764494b1601df 100644 (file)
@@ -27,6 +27,9 @@
 /* Define if floating-point instructions are supported */
 #undef RISCV_ENABLE_FPU
 
+/* Define if instruction cache simulator is enabled */
+#undef RISCV_ENABLE_ICSIM
+
 /* Define if instruction compression is supported */
 #undef RISCV_ENABLE_RVC
 
index ad0b90707b6cc600ecbaf21e6a8cc1674da19278..709daa8be4795ffbe17394202d079b6703ba589f 100755 (executable)
--- a/configure
+++ b/configure
@@ -639,6 +639,7 @@ enable_fpu
 enable_64bit
 enable_rvc
 enable_vec
+enable_icsim
 '
       ac_precious_vars='build_alias
 host_alias
@@ -1275,6 +1276,7 @@ Optional Features:
   --disable-64bit         Disable 64-bit mode
   --disable-rvc           Disable instruction compression
   --disable-vec           Disable vector processor
+  --disable-icsim         Enable instruction cache simulator
 
 Some influential environment variables:
   CC          C compiler command
@@ -4073,6 +4075,19 @@ if test "x$enable_vec" != "xno"; then :
 $as_echo "#define RISCV_ENABLE_VEC /**/" >>confdefs.h
 
 
+fi
+
+# Check whether --enable-icsim was given.
+if test "${enable_icsim+set}" = set; then :
+  enableval=$enable_icsim;
+fi
+
+if test "x$enable_icsim" = "xyes"; then :
+
+
+$as_echo "#define RISCV_ENABLE_ICSIM /**/" >>confdefs.h
+
+
 fi
 
 libopc=`dirname \`which riscv-gcc\``/../`$ac_config_guess`/riscv/lib/libopcodes.a
index 659243843b13e3b691651e3faabdf655369cbd94..5ced3203cb0b669c326009f3afcd98429e55929d 100644 (file)
@@ -107,7 +107,7 @@ int appserver_link_t::wait_for_packet()
         break;
       case APP_CMD_STOP:
         send_packet(&ackpacket);
-        exit(0);
+        throw quit_sim();
       case APP_CMD_READ_MEM:
         demand(p.addr % APP_DATA_ALIGN == 0, "misaligned address");
         demand(p.data_size % APP_DATA_ALIGN == 0, "misaligned data");
diff --git a/riscv/icsim.cc b/riscv/icsim.cc
new file mode 100644 (file)
index 0000000..73d6e9c
--- /dev/null
@@ -0,0 +1,55 @@
+#include "icsim.h"
+#include <stdexcept>
+#include <iostream>
+#include <iomanip>
+
+icsim_t::icsim_t(size_t _sets, size_t _ways, size_t _linesz)
+{
+  sets = _sets;
+  ways = _ways;
+  linesz = _linesz;
+
+  if(sets == 0 || (sets & (sets-1)))
+    throw std::logic_error("sets not a power of 2");
+  if(linesz == 0 || (linesz & (linesz-1)))
+    throw std::logic_error("linesz not a power of 2");
+  if(ways != 1)
+    throw std::logic_error("set associativity currently unsupported");
+
+  idx_mask = sets-1;
+  idx_shift = 0;
+  while(_linesz >>= 1)
+    idx_shift++;
+
+  tags = new uint64_t[sets*ways];
+  memset(tags, 0, sets*ways*sizeof(uint64_t));
+}
+
+icsim_t::~icsim_t()
+{
+  float mr = 100.0f*misses/accesses;
+  float cr = 100.0f*bytes_fetched/(4*accesses);
+
+  std::cout << "Instruction cache statsistics" << std::endl;
+  std::cout << "Bytes fetched: " << bytes_fetched << std::endl;
+  std::cout << "Hits: " << (accesses-misses) << std::endl;
+  std::cout << "Misses: " << misses << std::endl;
+  std::cout << "Miss rate: " << std::setprecision(3) << mr << '%' << std::endl;
+  std::cout << "RVC compression ratio: " << cr << '%' << std::endl;
+
+  delete [] tags;
+}
+
+void icsim_t::tick(uint64_t pc, int insnlen)
+{
+  accesses++;
+  bytes_fetched += insnlen;
+
+  size_t idx = (pc >> idx_shift) & idx_mask;
+  size_t tag = (pc >> idx_shift) | VALID;
+  if(tag != tags[idx])
+  {
+    misses++;
+    tags[idx] = tag;
+  }
+}
diff --git a/riscv/icsim.h b/riscv/icsim.h
new file mode 100644 (file)
index 0000000..122730c
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef _RISCV_ICSIM_H
+#define _RISCV_ICSIM_H
+
+#include <cstring>
+#include <stdint.h>
+
+class icsim_t
+{
+public:
+  icsim_t(size_t sets, size_t ways, size_t linesz);
+  ~icsim_t();
+
+  void tick(uint64_t pc, int insnlen);
+private:
+  size_t sets;
+  size_t ways;
+  size_t linesz;
+  size_t idx_shift;
+  size_t idx_mask;
+  
+  uint64_t accesses;
+  uint64_t misses;
+  uint64_t bytes_fetched;
+
+  uint64_t* tags;
+
+  static const uint64_t VALID = 1ULL << 63;
+};
+
+#endif
index f7bd8ce8d526f089453abc9b1c6ad2a1d0904cf6..289c200d441586440cea2a18ff707a673765af56 100644 (file)
@@ -1,6 +1,8 @@
 #include "decode.h"
 #include "trap.h"
 
+class processor_t;
+
 class mmu_t
 {
 public:
@@ -20,6 +22,7 @@ public:
 
   insn_t load_insn(reg_t addr, bool rvc)
   {
+    #ifdef RISCV_ENABLE_RVC
     check_align_and_bounds(addr, rvc ? 2 : 4, false, true);
     uint16_t lo = *(uint16_t*)(mem+addr);
     uint16_t hi = *(uint16_t*)(mem+addr+2);
@@ -28,6 +31,10 @@ public:
     insn.bits = lo | ((uint32_t)hi << 16);
 
     return insn;
+    #else
+    check_align_and_bounds(addr, 4, false, true);
+    return *(insn_t*)(mem+addr);
+    #endif
   }
 
   load_func(uint8)
@@ -81,4 +88,6 @@ private:
     check_align(addr, size, store, fetch);
     check_bounds(addr, size, store, fetch);
   }
+  
+  friend class processor_t;
 };
index 360b7553689607d4ac7788e3e410469f35453088..471afabecd559e6f0c7784bb0ac7cb6ace2a2572 100644 (file)
@@ -7,6 +7,7 @@
 #include "common.h"
 #include "config.h"
 #include "sim.h"
+#include "icsim.h"
 #include "softfloat.h"
 #include "platform.h" // softfloat isNaNF32UI, etc.
 #include "internals.h" // ditto
@@ -50,19 +51,31 @@ processor_t::processor_t(sim_t* _sim, char* _mem, size_t _memsz)
 
   static_assert(sizeof(insn_t) == 4);
   static_assert(sizeof(uint128_t) == 16 && sizeof(int128_t) == 16);
+
+  icsim = NULL;
+}
+
+processor_t::~processor_t()
+{
+  delete icsim;
 }
 
-void processor_t::init(uint32_t _id, char* _mem, size_t _memsz)
+void processor_t::init(uint32_t _id)
 {
   id = _id;
 
   for (int i=0; i<MAX_UTS; i++)
   {
-    uts[i] = new processor_t(sim, _mem, _memsz);
+    uts[i] = new processor_t(sim, mmu.mem, mmu.memsz);
+    uts[i]->id = id;
     uts[i]->set_sr(uts[i]->sr | SR_EF);
     uts[i]->set_sr(uts[i]->sr | SR_EV);
     uts[i]->utidx = i;
   }
+
+  #ifdef RISCV_ENABLE_ICSIM
+  icsim = new icsim_t(1024, 1, 32);
+  #endif
 }
 
 void processor_t::set_sr(uint32_t val)
@@ -121,6 +134,9 @@ void processor_t::step(size_t n, bool noisy)
         take_trap(trap_interrupt,noisy);
 
       insn_t insn = mmu.load_insn(pc, sr & SR_EC);
+      #ifdef RISCV_ENABLE_ICSIM
+      icsim->tick(pc, insn_length(insn));
+      #endif
   
       reg_t npc = pc + insn_length(insn);
 
index 34c31ac396725f13b35f4895abc04272e9800594..5c524c0fef183834c5b523f3c91ffc7d2f704a0f 100644 (file)
@@ -5,6 +5,7 @@
 #include <cstring>
 #include "trap.h"
 #include "mmu.h"
+#include "icsim.h"
 
 #define MAX_UTS 32
 
@@ -14,7 +15,8 @@ class processor_t
 {
 public:
   processor_t(sim_t* _sim, char* _mem, size_t _memsz);
-  void init(uint32_t _id, char* _mem, size_t _memsz);
+  ~processor_t();
+  void init(uint32_t _id);
   void step(size_t n, bool noisy);
 
 private:
@@ -71,6 +73,9 @@ private:
   int nfpr_use;
   processor_t* uts[MAX_UTS];
 
+  // icache sim
+  icsim_t* icsim;
+
   friend class sim_t;
 };
 
index 098e68b86a3a80fb36fdbbdf0df6c362aae467d8..83bb28637922f0393eeae6b63f0f3009146b0a1d 100644 (file)
@@ -35,5 +35,11 @@ int main(int argc, char** argv)
   appserver_link_t applink(tohost_fd,fromhost_fd);
 
   sim_t s(nprocs,MEMSIZE,&applink);
-  s.run(debug);
+  try
+  {
+    s.run(debug);
+  }
+  catch(quit_sim&)
+  {
+  }
 }
index 36c701a484851cedc8f5b1032b2814944bca0151..897b21fba563dbec25f26685af1b2b2169703920 100644 (file)
@@ -18,6 +18,11 @@ AS_IF([test "x$enable_vec" != "xno"], [
   AC_DEFINE([RISCV_ENABLE_VEC],,[Define if vector processor is supported])
 ])
 
+AC_ARG_ENABLE([icsim], AS_HELP_STRING([--disable-icsim], [Enable instruction cache simulator]))
+AS_IF([test "x$enable_icsim" = "xyes"], [
+  AC_DEFINE([RISCV_ENABLE_ICSIM],,[Define if instruction cache simulator is enabled])
+])
+
 libopc=`dirname \`which riscv-gcc\``/../`$ac_config_guess`/riscv/lib/libopcodes.a
 AC_CHECK_FILES([$libopc],[have_libopcodes="yes"],[have_libopcodes="no"])
 
index 6d55c8033876d848c66c85cfd0db6f511d10caa3..f53bc13335d79817f07b2f72b07aa3ecde1ce63b 100644 (file)
@@ -18,6 +18,7 @@ riscv_srcs = \
        processor.cc \
        sim.cc \
        trap.cc \
+       icsim.cc \
 
 riscv_test_srcs =
 
index fbea37444f4f7f30b8698f0c4ded13911d43ef4e..50264ed3db87c61acedf14f21c1fa3c1c1842266 100644 (file)
@@ -15,7 +15,7 @@ sim_t::sim_t(int _nprocs, size_t _memsz, appserver_link_t* _applink)
   demand(mem != MAP_FAILED, "couldn't allocate target machine's memory");
 
   for(int i = 0; i < (int)procs.size(); i++)
-    procs[i].init(i, mem, memsz);
+    procs[i].init(i);
 
   applink->init(this);
 }
@@ -141,7 +141,7 @@ void sim_t::interactive_run_proc(const std::string& cmd, const std::vector<std::
 
 void sim_t::interactive_quit(const std::string& cmd, const std::vector<std::string>& args)
 {
-  exit(0);
+  throw quit_sim();
 }
 
 reg_t sim_t::get_pc(const std::vector<std::string>& args)
index 47637136a91926cdd567edba353e040e8c73563d..722fe64268d7a27c812dd80f8dd037dcaa4ccb2b 100644 (file)
@@ -57,4 +57,6 @@ private:
   friend class appserver_link_t;
 };
 
+struct quit_sim {};
+
 #endif