/* 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
+ # 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"
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" ;;
# 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
--- /dev/null
+#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; })
--- /dev/null
+dummy_rocc_subproject_deps = \
+ spike \
+ riscv \
+ softfloat \
+
+dummy_rocc_srcs = \
+ dummy_rocc.cc \
--- /dev/null
+// 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");
+}
#include "trap.h"
#include <stdexcept>
+REGISTER_EXTENSION(hwacha, []() { return new hwacha_t; })
+
void ct_state_t::reset()
{
nxpr = 32;
hwacha_subproject_deps = \
+ spike \
riscv \
softfloat \
+++ /dev/null
-// 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");
-}
+++ /dev/null
-#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
#include "processor.h"
#include "disasm.h"
-#include <map>
-#include <string>
#include <vector>
#include <functional>
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
+++ /dev/null
-// 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;
-}
memtracer.h \
extension.h \
rocc.h \
- dummy-rocc.h \
insn_template.h \
mulhi.h \
#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];
+}
--- /dev/null
+// 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;
+}
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) {
spike_subproject_deps = \
- softfloat \
riscv \
- hwacha \
+ softfloat \
spike_install_prog_srcs = \
spike.cc \