aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@s144.Millennium.Berkeley.EDU>2011-04-15 14:32:54 -0700
committerAndrew Waterman <waterman@s144.Millennium.Berkeley.EDU>2011-04-15 14:33:12 -0700
commit481c9e8fd8a89106f70b73b6bd62e08f5b1e688a (patch)
tree4551a5e0246bab24823f3caac4cd1a8b66782011
parent402b4e8600281cb793bba0e493b37989a0db917f (diff)
downloadspike-481c9e8fd8a89106f70b73b6bd62e08f5b1e688a.zip
spike-481c9e8fd8a89106f70b73b6bd62e08f5b1e688a.tar.gz
spike-481c9e8fd8a89106f70b73b6bd62e08f5b1e688a.tar.bz2
[sim] added icache simulator (disabled by default)
-rw-r--r--config.h.in3
-rwxr-xr-xconfigure15
-rw-r--r--riscv/applink.cc2
-rw-r--r--riscv/icsim.cc55
-rw-r--r--riscv/icsim.h30
-rw-r--r--riscv/mmu.h9
-rw-r--r--riscv/processor.cc20
-rw-r--r--riscv/processor.h7
-rw-r--r--riscv/riscv-isa-run.cc8
-rw-r--r--riscv/riscv.ac5
-rw-r--r--riscv/riscv.mk.in1
-rw-r--r--riscv/sim.cc4
-rw-r--r--riscv/sim.h2
13 files changed, 154 insertions, 7 deletions
diff --git a/config.h.in b/config.h.in
index e592810..cf21aff 100644
--- a/config.h.in
+++ b/config.h.in
@@ -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
diff --git a/configure b/configure
index ad0b907..709daa8 100755
--- 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
@@ -4075,6 +4077,19 @@ $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
as_ac_File=`$as_echo "ac_cv_file_$libopc" | $as_tr_sh`
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $libopc" >&5
diff --git a/riscv/applink.cc b/riscv/applink.cc
index 6592438..5ced320 100644
--- a/riscv/applink.cc
+++ b/riscv/applink.cc
@@ -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
index 0000000..73d6e9c
--- /dev/null
+++ b/riscv/icsim.cc
@@ -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
index 0000000..122730c
--- /dev/null
+++ b/riscv/icsim.h
@@ -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
diff --git a/riscv/mmu.h b/riscv/mmu.h
index f7bd8ce..289c200 100644
--- a/riscv/mmu.h
+++ b/riscv/mmu.h
@@ -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;
};
diff --git a/riscv/processor.cc b/riscv/processor.cc
index 360b755..471afab 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -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);
diff --git a/riscv/processor.h b/riscv/processor.h
index 34c31ac..5c524c0 100644
--- a/riscv/processor.h
+++ b/riscv/processor.h
@@ -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;
};
diff --git a/riscv/riscv-isa-run.cc b/riscv/riscv-isa-run.cc
index 098e68b..83bb286 100644
--- a/riscv/riscv-isa-run.cc
+++ b/riscv/riscv-isa-run.cc
@@ -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&)
+ {
+ }
}
diff --git a/riscv/riscv.ac b/riscv/riscv.ac
index 36c701a..897b21f 100644
--- a/riscv/riscv.ac
+++ b/riscv/riscv.ac
@@ -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"])
diff --git a/riscv/riscv.mk.in b/riscv/riscv.mk.in
index 6d55c80..f53bc13 100644
--- a/riscv/riscv.mk.in
+++ b/riscv/riscv.mk.in
@@ -18,6 +18,7 @@ riscv_srcs = \
processor.cc \
sim.cc \
trap.cc \
+ icsim.cc \
riscv_test_srcs =
diff --git a/riscv/sim.cc b/riscv/sim.cc
index fbea374..50264ed 100644
--- a/riscv/sim.cc
+++ b/riscv/sim.cc
@@ -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)
diff --git a/riscv/sim.h b/riscv/sim.h
index 4763713..722fe64 100644
--- a/riscv/sim.h
+++ b/riscv/sim.h
@@ -57,4 +57,6 @@ private:
friend class appserver_link_t;
};
+struct quit_sim {};
+
#endif