Generic RISC-V ISS
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

169 lines
8.2 KiB

3 years ago
3 years ago
  1. ////////////////////////////////////////////////////////////////////////////////
  2. // Copyright (C) 2017, MINRES Technologies GmbH
  3. // All rights reserved.
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are met:
  7. //
  8. // 1. Redistributions of source code must retain the above copyright notice,
  9. // this list of conditions and the following disclaimer.
  10. //
  11. // 2. Redistributions in binary form must reproduce the above copyright notice,
  12. // this list of conditions and the following disclaimer in the documentation
  13. // and/or other materials provided with the distribution.
  14. //
  15. // 3. Neither the name of the copyright holder nor the names of its contributors
  16. // may be used to endorse or promote products derived from this software
  17. // without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  20. // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21. // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22. // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  23. // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  24. // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  25. // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  26. // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  27. // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  28. // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  29. // POSSIBILITY OF SUCH DAMAGE.
  30. //
  31. // Contributors:
  32. // eyck@minres.com - initial implementation
  33. //
  34. //
  35. ////////////////////////////////////////////////////////////////////////////////
  36. #include <boost/program_options.hpp>
  37. #include <iss/log_categories.h>
  38. #include <sstream>
  39. #include <sysc/SiFive/platform.h>
  40. #include "scc/configurer.h"
  41. #include "scc/report.h"
  42. #include "scc/scv_tr_db.h"
  43. #include "scc/tracer.h"
  44. #include <cci_utils/broker.h>
  45. #include <iss/jit/jit_helper.h>
  46. using namespace sysc;
  47. namespace po = boost::program_options;
  48. namespace {
  49. const size_t ERROR_IN_COMMAND_LINE = 1;
  50. const size_t SUCCESS = 0;
  51. const size_t ERROR_UNHANDLED_EXCEPTION = 2;
  52. } // namespace
  53. int sc_main(int argc, char *argv[]) {
  54. // sc_report_handler::set_handler(my_report_handler);
  55. scc::Logger<>::reporting_level() = logging::ERROR;
  56. cci::cci_register_broker(new cci_utils::broker("Global Broker"));
  57. ///////////////////////////////////////////////////////////////////////////
  58. // CLI argument parsing
  59. ///////////////////////////////////////////////////////////////////////////
  60. po::options_description desc("Options");
  61. // clang-format off
  62. desc.add_options()
  63. ("help,h", "Print help message")
  64. ("verbose,v", po::value<int>()->implicit_value(3), "Sets logging verbosity")
  65. ("log-file", po::value<std::string>(), "Sets default log file.")
  66. ("disass,d", po::value<std::string>()->implicit_value(""), "Enables disassembly")
  67. ("elf,l", po::value<std::string>(), "ELF file to load")
  68. ("gdb-port,g", po::value<unsigned short>()->default_value(0), "enable gdb server and specify port to use")
  69. ("dump-ir", "dump the intermediate representation")
  70. ("quantum", po::value<unsigned>(), "SystemC quantum time in ns")
  71. ("reset,r", po::value<std::string>(), "reset address")
  72. ("trace,t", po::value<unsigned>()->default_value(0), "enable tracing, or combintation of 1=signals and 2=TX text, 4=TX compressed text, 6=TX in SQLite")
  73. ("max_time,m", po::value<std::string>(), "maximum time to run")
  74. ("config-file,c", po::value<std::string>()->default_value(""), "read configuration from file")
  75. ("dump-config", po::value<std::string>()->default_value(""), "dump configuration to file file");
  76. // clang-format on
  77. po::variables_map vm;
  78. try {
  79. po::store(po::parse_command_line(argc, argv, desc), vm); // can throw
  80. // --help option
  81. if (vm.count("help")) {
  82. std::cout << "DBT-RISE-RiscV simulator for RISC-V" << std::endl << desc << std::endl;
  83. return SUCCESS;
  84. }
  85. po::notify(vm); // throws on error, so do after help in case
  86. // there are any problems
  87. } catch (po::error &e) {
  88. std::cerr << "ERROR: " << e.what() << std::endl << std::endl;
  89. std::cerr << desc << std::endl;
  90. return ERROR_IN_COMMAND_LINE;
  91. }
  92. if (vm.count("verbose")) {
  93. auto l = logging::as_log_level(vm["verbose"].as<int>());
  94. LOGGER(DEFAULT)::reporting_level() = l;
  95. LOGGER(connection)::reporting_level() = l;
  96. LOGGER(SystemC)::reporting_level() = l;
  97. scc::Logger<>::reporting_level() = l;
  98. }
  99. if (vm.count("log-file")) {
  100. // configure the connection logger
  101. auto f = fopen(vm["log-file"].as<std::string>().c_str(), "w");
  102. LOG_OUTPUT(DEFAULT)::stream() = f;
  103. LOG_OUTPUT(connection)::stream() = f;
  104. LOG_OUTPUT(SystemC)::stream() = f;
  105. }
  106. ///////////////////////////////////////////////////////////////////////////
  107. // set up infrastructure
  108. ///////////////////////////////////////////////////////////////////////////
  109. iss::init_jit(argc, argv);
  110. ///////////////////////////////////////////////////////////////////////////
  111. // set up tracing & transaction recording
  112. ///////////////////////////////////////////////////////////////////////////
  113. auto trace_val = vm["trace"].as<unsigned>();
  114. scc::tracer trace("simple_system", static_cast<scc::tracer::file_type>(trace_val >> 1), trace_val != 0);
  115. ///////////////////////////////////////////////////////////////////////////
  116. // set up configuration
  117. ///////////////////////////////////////////////////////////////////////////
  118. scc::configurer cfg(vm["config-file"].as<std::string>());
  119. ///////////////////////////////////////////////////////////////////////////
  120. // instantiate top level
  121. ///////////////////////////////////////////////////////////////////////////
  122. platform i_simple_system("i_simple_system");
  123. // sr_report_handler::add_sc_object_to_filter(&i_simple_system.i_master,
  124. // sc_core::SC_WARNING, sc_core::SC_MEDIUM);
  125. if(vm["dump-config"].as<std::string>().size()>0){
  126. std::ofstream of{vm["dump-config"].as<std::string>()};
  127. if(of.is_open())
  128. cfg.dump_configuration(of);
  129. }
  130. cfg.configure();
  131. // overwrite with command line settings
  132. if (vm["gdb-port"].as<unsigned short>())
  133. cfg.set_value("i_simple_system.i_core_complex.gdb_server_port", vm["gdb-port"].as<unsigned short>());
  134. if (vm.count("dump-ir"))
  135. cfg.set_value("i_simple_system.i_core_complex.dump_ir", vm.count("dump-ir") != 0);
  136. if (vm.count("elf"))
  137. cfg.set_value("i_simple_system.i_core_complex.elf_file", vm["elf"].as<std::string>());
  138. if (vm.count("quantum"))
  139. tlm::tlm_global_quantum::instance().set(sc_core::sc_time(vm["quantum"].as<unsigned>(), sc_core::SC_NS));
  140. if (vm.count("reset")) {
  141. auto str = vm["reset"].as<std::string>();
  142. uint64_t start_address = str.find("0x") == 0 ? std::stoull(str.substr(2), 0, 16) : std::stoull(str, 0, 10);
  143. cfg.set_value("i_simple_system.i_core_complex.reset_address", start_address);
  144. }
  145. if (vm.count("disass")) {
  146. cfg.set_value("i_simple_system.i_core_complex.enable_disass", true);
  147. LOGGER(disass)::reporting_level() = logging::INFO;
  148. auto file_name = vm["disass"].as<std::string>();
  149. if (file_name.length() > 0) {
  150. LOG_OUTPUT(disass)::stream() = fopen(file_name.c_str(), "w");
  151. LOGGER(disass)::print_time() = false;
  152. LOGGER(disass)::print_severity() = false;
  153. }
  154. }
  155. ///////////////////////////////////////////////////////////////////////////
  156. // run simulation
  157. ///////////////////////////////////////////////////////////////////////////
  158. if(vm.count("max_time")){
  159. sc_core::sc_time max_time = scc::parse_from_string(vm["max_time"].as<std::string>());
  160. sc_core::sc_start(max_time);
  161. } else
  162. sc_core::sc_start();
  163. if (!sc_core::sc_end_of_simulation_invoked()) sc_core::sc_stop();
  164. return 0;
  165. }