Factor out the dummy RoCC accelerator
authorAndrew Waterman <waterman@cs.berkeley.edu>
Tue, 25 Nov 2014 21:39:53 +0000 (13:39 -0800)
committerAndrew Waterman <waterman@cs.berkeley.edu>
Tue, 25 Nov 2014 22:40:51 +0000 (14:40 -0800)
18 files changed:
config.h.in
configure
configure.ac
dummy_rocc/dummy_rocc.ac [new file with mode: 0644]
dummy_rocc/dummy_rocc.cc [new file with mode: 0644]
dummy_rocc/dummy_rocc.mk.in [new file with mode: 0644]
dummy_rocc/dummy_rocc_test.c [new file with mode: 0644]
hwacha/hwacha.cc
hwacha/hwacha.mk.in
riscv/dummy-rocc-test.c [deleted file]
riscv/dummy-rocc.h [deleted file]
riscv/extension.h
riscv/riscv-dis.cc [deleted file]
riscv/riscv.mk.in
spike/extensions.cc
spike/riscv-dis.cc [new file with mode: 0644]
spike/spike.cc
spike/spike.mk.in

index 42d4d223a41cbbdf88a2fcae8e83f8ebb50520c3..12aeebdaef1d94857904c7dbbe0f271acb00af4a 100644 (file)
@@ -1,5 +1,8 @@
 /* config.h.in.  Generated from configure.ac by autoheader.  */
 
+/* Define if subproject MCPPBS_SPROJ_NORM is enabled */
+#undef DUMMY_ROCC_ENABLED
+
 /* Define to 1 if you have the `dl' library (-ldl). */
 #undef HAVE_LIBDL
 
index abddde5249399e3808c0043230120aaa0605b432..e98db52adc4ff05b1fa088a6137492bad0b94915 100755 (executable)
--- a/configure
+++ b/configure
@@ -4301,6 +4301,51 @@ $as_echo "#define HWACHA_ENABLED /**/" >>confdefs.h
 
 
 
+    # Add subproject to our running list
+
+    subprojects="$subprojects dummy_rocc"
+
+    # Process the subproject appropriately. If enabled add it to the
+    # $enabled_subprojects running shell variable, set a
+    # SUBPROJECT_ENABLED C define, and include the appropriate
+    # 'subproject.ac'.
+
+
+      { $as_echo "$as_me:${as_lineno-$LINENO}: configuring default subproject : dummy_rocc" >&5
+$as_echo "$as_me: configuring default subproject : dummy_rocc" >&6;}
+      ac_config_files="$ac_config_files dummy_rocc.mk:dummy_rocc/dummy_rocc.mk.in"
+
+      enable_dummy_rocc_sproj="yes"
+      subprojects_enabled="$subprojects_enabled dummy_rocc"
+
+$as_echo "#define DUMMY_ROCC_ENABLED /**/" >>confdefs.h
+
+
+
+
+
+
+    # Determine if this is a required or an optional subproject
+
+
+
+    # Determine if there is a group with the same name
+
+
+
+    # Create variations of the subproject name suitable for use as a CPP
+    # enabled define, a shell enabled variable, and a shell function
+
+
+
+
+
+
+
+
+
+
+
     # Add subproject to our running list
 
     subprojects="$subprojects softfloat"
@@ -5147,6 +5192,7 @@ do
   case $ac_config_target in
     "riscv.mk") CONFIG_FILES="$CONFIG_FILES riscv.mk:riscv/riscv.mk.in" ;;
     "hwacha.mk") CONFIG_FILES="$CONFIG_FILES hwacha.mk:hwacha/hwacha.mk.in" ;;
+    "dummy_rocc.mk") CONFIG_FILES="$CONFIG_FILES dummy_rocc.mk:dummy_rocc/dummy_rocc.mk.in" ;;
     "softfloat.mk") CONFIG_FILES="$CONFIG_FILES softfloat.mk:softfloat/softfloat.mk.in" ;;
     "spike.mk") CONFIG_FILES="$CONFIG_FILES spike.mk:spike/spike.mk.in" ;;
     "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
index d6fb7e5df9a75044dc1ca6ec24af411878ea4f53..89d4dcf2a56c14b9426680f085332105231b96bc 100644 (file)
@@ -82,7 +82,7 @@ AC_SUBST([CXXFLAGS],["-Wall -Wno-unused -O2 -std=c++11"])
 # The '*' suffix indicates an optional subproject. The '**' suffix
 # indicates an optional subproject which is also the name of a group.
 
-MCPPBS_SUBPROJECTS([ riscv, hwacha, softfloat, spike ])
+MCPPBS_SUBPROJECTS([ riscv, hwacha, dummy_rocc, softfloat, spike ])
 
 #-------------------------------------------------------------------------
 # MCPPBS subproject groups
diff --git a/dummy_rocc/dummy_rocc.ac b/dummy_rocc/dummy_rocc.ac
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/dummy_rocc/dummy_rocc.cc b/dummy_rocc/dummy_rocc.cc
new file mode 100644 (file)
index 0000000..85ab7aa
--- /dev/null
@@ -0,0 +1,47 @@
+#include "rocc.h"
+#include "mmu.h"
+#include <cstring>
+
+class dummy_rocc_t : public rocc_t
+{
+ public:
+  const char* name() { return "dummy_rocc"; }
+
+  reg_t custom0(rocc_insn_t insn, reg_t xs1, reg_t xs2)
+  {
+    reg_t prev_acc = acc[insn.rs2];
+
+    if (insn.rs2 >= num_acc)
+      illegal_instruction();
+
+    switch (insn.funct)
+    {
+      case 0: // acc <- xs1
+        acc[insn.rs2] = xs1;
+        break;
+      case 1: // xd <- acc (the only real work is the return statement below)
+        break;
+      case 2: // acc[rs2] <- Mem[xs1]
+        acc[insn.rs2] = p->get_mmu()->load_uint64(xs1);
+        break;
+      case 3: // acc[rs2] <- accX + xs1
+        acc[insn.rs2] += xs1;
+        break;
+      default:
+        illegal_instruction();
+    }
+
+    return prev_acc; // in all cases, xd <- previous value of acc[rs2]
+  }
+
+  dummy_rocc_t()
+  {
+    memset(acc, 0, sizeof(acc));
+  }
+
+ private:
+  static const int num_acc = 4;
+  reg_t acc[num_acc];
+};
+
+REGISTER_EXTENSION(dummy_rocc, []() { return new dummy_rocc_t; })
diff --git a/dummy_rocc/dummy_rocc.mk.in b/dummy_rocc/dummy_rocc.mk.in
new file mode 100644 (file)
index 0000000..298b9f9
--- /dev/null
@@ -0,0 +1,7 @@
+dummy_rocc_subproject_deps = \
+       spike \
+       riscv \
+       softfloat \
+
+dummy_rocc_srcs = \
+       dummy_rocc.cc \
diff --git a/dummy_rocc/dummy_rocc_test.c b/dummy_rocc/dummy_rocc_test.c
new file mode 100644 (file)
index 0000000..94de8c0
--- /dev/null
@@ -0,0 +1,29 @@
+// The following is a RISC-V program to test the functionality of the
+// dummy RoCC accelerator.
+// Compile with riscv64-unknown-elf-gcc dummy_rocc_test.c
+// Run with spike --extension=dummy_rocc pk a.out
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdint.h>
+
+int main() {
+  uint64_t x = 123, y = 456, z = 0;
+  // load x into accumulator 2 (funct=0)
+  asm volatile ("custom0 x0, %0, 2, 0" : : "r"(x));
+  // read it back into z (funct=1) to verify it
+  asm volatile ("custom0 %0, x0, 2, 1" : "=r"(z));
+  assert(z == x);
+  // accumulate 456 into it (funct=3)
+  asm volatile ("custom0 x0, %0, 2, 3" : : "r"(y));
+  // verify it
+  asm volatile ("custom0 %0, x0, 2, 1" : "=r"(z));
+  assert(z == x+y);
+  // do it all again, but initialize acc2 via memory this time (funct=2)
+  asm volatile ("custom0 x0, %0, 2, 2" : : "r"(&x));
+  asm volatile ("custom0 x0, %0, 2, 3" : : "r"(y));
+  asm volatile ("custom0 %0, x0, 2, 1" : "=r"(z));
+  assert(z == x+y);
+
+  printf("success!\n");
+}
index 1a89d733d1a3f18931def2b794f6f00cafa4a9a1..fdd215eb1d884e00db8dff4d9f25cdfa1b172457 100644 (file)
@@ -4,6 +4,8 @@
 #include "trap.h"
 #include <stdexcept>
 
+REGISTER_EXTENSION(hwacha, []() { return new hwacha_t; })
+
 void ct_state_t::reset()
 {
   nxpr = 32;
index b4f375ebbcc7c412aaf017671f300ba64f87890f..362487977838fc976cfe541bef42796d247d5afd 100644 (file)
@@ -1,4 +1,5 @@
 hwacha_subproject_deps = \
+       spike \
        riscv \
        softfloat \
 
diff --git a/riscv/dummy-rocc-test.c b/riscv/dummy-rocc-test.c
deleted file mode 100644 (file)
index ce48179..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-// The following is a RISC-V program to test the functionality of the
-// dummy RoCC accelerator.
-// Compile with riscv-gcc dummy-rocc-test.c
-// Run with spike --extension=dummy pk a.out
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdint.h>
-
-int main() {
-  uint64_t x = 123, y = 456, z = 0;
-  // load x into accumulator 2 (funct=0)
-  asm volatile ("custom0 x0, %0, 2, 0" : : "r"(x));
-  // read it back into z (funct=1) to verify it
-  asm volatile ("custom0 %0, x0, 2, 1" : "=r"(z));
-  assert(z == x);
-  // accumulate 456 into it (funct=3)
-  asm volatile ("custom0 x0, %0, 2, 3" : : "r"(y));
-  // verify it
-  asm volatile ("custom0 %0, x0, 2, 1" : "=r"(z));
-  assert(z == x+y);
-  // do it all again, but initialize acc2 via memory this time (funct=2)
-  asm volatile ("custom0 x0, %0, 2, 2" : : "r"(&x));
-  asm volatile ("custom0 x0, %0, 2, 3" : : "r"(y));
-  asm volatile ("custom0 %0, x0, 2, 1" : "=r"(z));
-  assert(z == x+y);
-
-  printf("success!\n");
-}
diff --git a/riscv/dummy-rocc.h b/riscv/dummy-rocc.h
deleted file mode 100644 (file)
index 75e0722..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-#ifndef _RISCV_DUMMY_ROCC_H
-#define _RISCV_DUMMY_ROCC_H
-
-#include "rocc.h"
-#include "mmu.h"
-
-class dummy_rocc_t : public rocc_t
-{
- public:
-  const char* name() { return "dummy"; }
-
-  reg_t custom0(rocc_insn_t insn, reg_t xs1, reg_t xs2)
-  {
-    reg_t prev_acc = acc[insn.rs2];
-
-    if (insn.rs2 > num_acc)
-      illegal_instruction();
-
-    switch (insn.funct)
-    {
-      case 0: // acc <- xs1
-        acc[insn.rs2] = xs1;
-        break;
-      case 1: // xd <- acc (the only real work is the return statement below)
-        break;
-      case 2: // acc[rs2] <- Mem[xs1]
-        acc[insn.rs2] = p->get_mmu()->load_uint64(xs1);
-        break;
-      case 3: // acc[rs2] <- accX + xs1
-        acc[insn.rs2] += xs1;
-        break;
-      default:
-        illegal_instruction();
-    }
-
-    return prev_acc; // in all cases, xd <- previous value of acc[rs2]
-  }
-  
-  void reset()
-  {
-    for(int i = 0; i < num_acc; i++) acc[i] = 0;
-  }
-
- private:
-  static const int num_acc = 4;
-  reg_t acc[num_acc];
-};
-
-#endif
index cce8345121f61a9f2fe554d0f284b810977236f5..f73a5a82d592b70f9b9de9e55fce5dea26e2757e 100644 (file)
@@ -3,8 +3,6 @@
 
 #include "processor.h"
 #include "disasm.h"
-#include <map>
-#include <string>
 #include <vector>
 #include <functional>
 
@@ -27,11 +25,12 @@ class extension_t
   void clear_interrupt();
 };
 
-std::map<std::string, std::function<extension_t*()>>& extensions();
+std::function<extension_t*()> find_extension(const char* name);
+void register_extension(const char* name, std::function<extension_t*()> f);
 
 #define REGISTER_EXTENSION(name, constructor) \
   class register_##name { \
-    public: register_##name() { extensions()[#name] = constructor; } \
+    public: register_##name() { register_extension(#name, constructor); } \
   }; static register_##name dummy_##name;
 
 #endif
diff --git a/riscv/riscv-dis.cc b/riscv/riscv-dis.cc
deleted file mode 100644 (file)
index 19d579d..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-// See LICENSE for license details.
-
-// This little program finds occurrences of strings like
-//  DASM(ffabc013)
-// in its input, then replaces them with the disassembly
-// enclosed hexadecimal number, interpreted as a RISC-V
-// instruction.
-
-#include "disasm.h"
-#include "extension.h"
-#include <iostream>
-#include <string>
-#include <cstdint>
-#include <fesvr/option_parser.h>
-using namespace std;
-
-int main(int argc, char** argv)
-{
-  string s;
-  disassembler_t d;
-
-  std::function<extension_t*()> extension;
-  option_parser_t parser;
-  parser.option(0, "extension", 1, [&](const char* s){
-    if (!extensions().count(s))
-      fprintf(stderr, "unknown extension %s!\n", s), exit(-1);
-    extension = extensions()[s];
-
-    for (auto disasm_insn : extension()->get_disasms())
-      d.add_insn(disasm_insn);
-  });
-
-  while (getline(cin, s))
-  {
-    for (size_t start = 0; (start = s.find("DASM(", start)) != string::npos; )
-    {
-      size_t end = s.find(')', start);
-      if (end == string::npos)
-        break;
-
-      size_t numstart = start + strlen("DASM(");
-      uint32_t n = strtoul(&s[numstart], NULL, 16);
-
-      string dis = d.disassemble(*(insn_t*)&n);
-
-      s = s.substr(0, start) + dis + s.substr(end+1);
-      start += dis.length();
-    }
-
-    cout << s << '\n';
-  }
-
-  return 0;
-}
index c5a90552df3f53b95de5535f4b9a57bbec1d6b5b..0d5869dae2a290c409c64c8d3490e33bae74fe7a 100644 (file)
@@ -19,7 +19,6 @@ riscv_hdrs = \
        memtracer.h \
        extension.h \
        rocc.h \
-       dummy-rocc.h \
        insn_template.h \
        mulhi.h \
 
index 0d22a95d932f956a4a91fe5055a11b0f7f018e9f..315621fd86fbbb93822bc00763b7eecc2670585e 100644 (file)
@@ -1,14 +1,35 @@
 #include "extension.h"
-#include "hwacha.h"
-#include "dummy-rocc.h"
+#include <string>
+#include <map>
+#include <dlfcn.h>
 
-REGISTER_EXTENSION(dummy, []() { return new dummy_rocc_t; })
-REGISTER_EXTENSION(hwacha, []() { return new hwacha_t; })
-
-// Static constructors want to make use of the extensions map, so we
-// access it through a function call to guarantee initialization order.
-std::map<std::string, std::function<extension_t*()>>& extensions()
+static std::map<std::string, std::function<extension_t*()>>& extensions()
 {
   static std::map<std::string, std::function<extension_t*()>> v;
   return v;
 }
+
+void register_extension(const char* name, std::function<extension_t*()> f)
+{
+  extensions()[name] = f;
+}
+
+std::function<extension_t*()> find_extension(const char* name)
+{
+  if (!extensions().count(name)) {
+    // try to find extension xyz by loading libxyz.so
+    std::string libname = std::string("lib") + name + ".so";
+    if (!dlopen(libname.c_str(), RTLD_LAZY)) {
+      fprintf(stderr, "couldn't find extension '%s' (or library '%s')\n",
+              name, libname.c_str());
+      exit(-1);
+    }
+    if (!extensions().count(name)) {
+      fprintf(stderr, "couldn't find extension '%s' in shared library '%s'\n",
+              name, libname.c_str());
+      exit(-1);
+    }
+  }
+
+  return extensions()[name];
+}
diff --git a/spike/riscv-dis.cc b/spike/riscv-dis.cc
new file mode 100644 (file)
index 0000000..89c4b74
--- /dev/null
@@ -0,0 +1,47 @@
+// See LICENSE for license details.
+
+// This little program finds occurrences of strings like
+//  DASM(ffabc013)
+// in its input, then replaces them with the disassembly
+// enclosed hexadecimal number, interpreted as a RISC-V
+// instruction.
+
+#include "disasm.h"
+#include "extension.h"
+#include <iostream>
+#include <string>
+#include <cstdint>
+#include <fesvr/option_parser.h>
+using namespace std;
+
+int main(int argc, char** argv)
+{
+  string s;
+  disassembler_t d;
+
+  std::function<extension_t*()> extension;
+  option_parser_t parser;
+  parser.option(0, "extension", 1, [&](const char* s){extension = find_extension(s);});
+
+  while (getline(cin, s))
+  {
+    for (size_t start = 0; (start = s.find("DASM(", start)) != string::npos; )
+    {
+      size_t end = s.find(')', start);
+      if (end == string::npos)
+        break;
+
+      size_t numstart = start + strlen("DASM(");
+      uint32_t n = strtoul(&s[numstart], NULL, 16);
+
+      string dis = d.disassemble(*(insn_t*)&n);
+
+      s = s.substr(0, start) + dis + s.substr(end+1);
+      start += dis.length();
+    }
+
+    cout << s << '\n';
+  }
+
+  return 0;
+}
index 5c8901cbe84bfdb561cc7b79b455df86b3a3a33e..ab5cea554957a97e388e7d71e351c94f8bffb332 100644 (file)
@@ -51,11 +51,7 @@ int main(int argc, char** argv)
   parser.option(0, "ic", 1, [&](const char* s){ic.reset(new icache_sim_t(s));});
   parser.option(0, "dc", 1, [&](const char* s){dc.reset(new dcache_sim_t(s));});
   parser.option(0, "l2", 1, [&](const char* s){l2.reset(cache_sim_t::construct(s, "L2$"));});
-  parser.option(0, "extension", 1, [&](const char* s){
-    if (!extensions().count(s))
-      fprintf(stderr, "unknown extension %s!\n", s), exit(-1);
-    extension = extensions()[s];
-  });
+  parser.option(0, "extension", 1, [&](const char* s){extension = find_extension(s);});
   parser.option(0, "extlib", 1, [&](const char *s){
     void *lib = dlopen(s, RTLD_NOW | RTLD_GLOBAL);
     if (lib == NULL) {
index 7534e8648fb8e37d829a8eb5977366c75d070031..280fa6c687d4bd0d5419364f7466d0177a32b8fa 100644 (file)
@@ -1,7 +1,6 @@
 spike_subproject_deps = \
-       softfloat \
        riscv \
-       hwacha \
+       softfloat \
 
 spike_install_prog_srcs = \
        spike.cc \