mirror of
https://github.com/Minres/RISCV-VP.git
synced 2025-12-17 08:51:35 +00:00
initial version
This commit is contained in:
113
src/CLIParser.cpp
Normal file
113
src/CLIParser.cpp
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2019 -2021 MINRES Technolgies GmbH
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "CLIParser.h"
|
||||
#include <scc/report.h>
|
||||
#include <iostream>
|
||||
#include <iss/log_categories.h>
|
||||
#include <scc/report.h>
|
||||
#include <stdexcept>
|
||||
#include <unordered_set>
|
||||
#ifdef ERROR
|
||||
#undef ERROR
|
||||
#endif
|
||||
namespace po = boost::program_options;
|
||||
using namespace sc_core;
|
||||
|
||||
namespace {
|
||||
std::unordered_set<std::string> backend_opts = {"interp", "tcc", "llvm", "asmjit"};
|
||||
}
|
||||
CLIParser::CLIParser(int argc, char *argv[])
|
||||
: desc("Options")
|
||||
, valid(false) {
|
||||
build();
|
||||
try {
|
||||
po::store(po::parse_command_line(argc, argv, desc), vm_); // can throw
|
||||
// --help option
|
||||
if (vm_.count("help")) {
|
||||
std::cout << "DBT-RISE-TGC based virtual platform of TGC cores" << std::endl << desc << std::endl;
|
||||
}
|
||||
po::notify(vm_); // throws on error, so do after help in case there are any problems
|
||||
valid = true;
|
||||
if(backend_opts.find(vm_["backend"].as<std::string>())== std::end(backend_opts))
|
||||
throw po::error("Illegal value for switch backend");
|
||||
} catch (po::error &e) {
|
||||
std::cerr << "ERROR: " << e.what() << std::endl << std::endl;
|
||||
std::cerr << desc << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
auto log_level = vm_["verbose"].as<scc::log>();
|
||||
auto log_level_num = static_cast<unsigned>(log_level);
|
||||
LOGGER(DEFAULT)::reporting_level() = logging::as_log_level(log_level_num > 6 ? 6 : log_level_num);;
|
||||
LOGGER(DEFAULT)::print_time() = false;
|
||||
LOG_OUTPUT(DEFAULT)::ostream() = &std::cout;
|
||||
LOGGER(connection)::reporting_level() = logging::as_log_level(log_level_num > 4 ? log_level_num-1 : log_level_num);;
|
||||
LOGGER(connection)::print_time() = false;
|
||||
LOG_OUTPUT(connection)::ostream() = &std::cout;
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// configure logging
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
scc::init_logging(scc::LogConfig()
|
||||
.logFileName(vm_["log-file"].as<std::string>())
|
||||
.logLevel(vm_["verbose"].as<scc::log>())
|
||||
.logFilterRegex(vm_["log-filter"].as<std::string>())
|
||||
.logAsync(!vm_["log-sync"].as<bool>()));
|
||||
scc::stream_redirection cout_redir(std::cout, scc::log::DEBUG);
|
||||
scc::stream_redirection cerr_redir(std::cerr, scc::log::ERROR);
|
||||
sc_core::sc_report_handler::set_actions("/IEEE_Std_1666/deprecated", sc_core::SC_DO_NOTHING);
|
||||
sc_core::sc_report_handler::set_actions(sc_core::SC_ID_MORE_THAN_ONE_SIGNAL_DRIVER_, sc_core::SC_DO_NOTHING);
|
||||
sc_core::sc_report_handler::set_actions(sc_core::SC_ERROR, sc_core::SC_LOG | sc_core::SC_CACHE_REPORT | sc_core::SC_DISPLAY | sc_core::SC_STOP);
|
||||
}
|
||||
|
||||
void CLIParser::build() {
|
||||
// clang-format off
|
||||
desc.add_options()
|
||||
("help,h",
|
||||
"Print help message")
|
||||
("verbose,v", po::value<scc::log>()->default_value(scc::log::INFO),
|
||||
"debug output level (NONE, FATAL, ERROR, WARNING, INFO, DEBUG, TRACE, TRACEALL)")
|
||||
("log-file,l", po::value<std::string>()->default_value(""),
|
||||
"log file name")
|
||||
("log-filter", po::value<std::string>()->default_value(""),
|
||||
"log filter regular expression name")
|
||||
("log-sync", po::bool_switch(),
|
||||
"Disable asynchronous logging")
|
||||
("disass,d", po::value<std::string>()->implicit_value(""),
|
||||
"Enables disassembly")
|
||||
("elf,f", po::value<std::string>(),
|
||||
"ELF file to load")
|
||||
("gdb-port,g", po::value<unsigned short>()->default_value(0),
|
||||
"enable gdb server and specify port to use")
|
||||
("backend", po::value<std::string>()->default_value("interp"),
|
||||
"the ISS backend to use, options are: interp, tcc")
|
||||
("isa", po::value<std::string>()->default_value("tgc5c"),
|
||||
"core or isa name to use for simulation, use '?' to get list")
|
||||
("dump-ir",
|
||||
"dump the intermediate representation")
|
||||
("dump-structure", po::value<std::string>(),
|
||||
"dump model structure to ELK file")
|
||||
("quantum", po::value<unsigned>(),
|
||||
"SystemC quantum time in ns")
|
||||
("reset,r", po::value<std::string>(),
|
||||
"reset address")
|
||||
("trace-level,t", po::value<unsigned>()->default_value(0),
|
||||
"enable tracing, or combination of 1=signals and 2=TX")
|
||||
("trace-default-on",
|
||||
"enables tracing for all unspecified modules")
|
||||
("trace-file", po::value<std::string>()->default_value("system"),
|
||||
"set th ename of the trace file")
|
||||
("max_time,m", po::value<std::string>(),
|
||||
"maximum time to run")
|
||||
("config-file,c", po::value<std::string>()->default_value(""),
|
||||
"read configuration from file")
|
||||
("plugin,p", po::value<std::vector<std::string>>(),
|
||||
"plugin(s) to activate")
|
||||
("dump-config,dc", po::value<std::string>()->default_value(""),
|
||||
"dump configuration to file file");
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
CLIParser::~CLIParser() = default;
|
||||
36
src/CLIParser.h
Normal file
36
src/CLIParser.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2019 -2021 MINRES Technolgies GmbH
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef PLATFORM_SRC_CLIPARSER_H_
|
||||
#define PLATFORM_SRC_CLIPARSER_H_
|
||||
|
||||
#include <boost/program_options.hpp>
|
||||
#include <scc/report.h>
|
||||
#include <memory>
|
||||
|
||||
class CLIParser {
|
||||
public:
|
||||
CLIParser(int argc, char *argv[]);
|
||||
|
||||
virtual ~CLIParser();
|
||||
|
||||
bool is_valid() { return valid; }
|
||||
|
||||
const boost::program_options::variables_map &vm() { return vm_; }
|
||||
|
||||
bool is_set(const char *option) { return vm_.count(option) != 0; }
|
||||
|
||||
template <typename T> const T &get(const char *option) { return vm_[option].as<T>(); }
|
||||
|
||||
private:
|
||||
void build();
|
||||
bool valid;
|
||||
boost::program_options::variables_map vm_;
|
||||
boost::program_options::options_description desc;
|
||||
std::array<std::unique_ptr<scc::stream_redirection>, 2> redir;
|
||||
};
|
||||
|
||||
#endif /* PLATFORM_SRC_CLIPARSER_H_ */
|
||||
38
src/CMakeLists.txt
Normal file
38
src/CMakeLists.txt
Normal file
@@ -0,0 +1,38 @@
|
||||
#
|
||||
# Copyright (c) 2019 -2021 MINRES Technolgies GmbH
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
project(riscv-vp LANGUAGES C CXX VERSION 0.0.1)
|
||||
|
||||
include(flink)
|
||||
|
||||
find_package(Boost COMPONENTS program_options thread REQUIRED)
|
||||
###############################################################################
|
||||
#
|
||||
###############################################################################
|
||||
set(CMAKE_INSTALL_RPATH $ORIGIN/../${CMAKE_INSTALL_LIBDIR})
|
||||
add_executable(${PROJECT_NAME}
|
||||
sc_main.cpp
|
||||
CLIParser.cpp
|
||||
vp/tb.cpp
|
||||
vp/system.cpp
|
||||
)
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR})
|
||||
target_force_link_libraries(${PROJECT_NAME} PUBLIC dbt-rise-riscv_sc)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC vpvper_generic vpvper_minres ${BOOST_program_options_LIBRARY})
|
||||
if(TARGET Boost::program_options)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC Boost::program_options Boost::thread)
|
||||
else()
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC ${BOOST_program_options_LIBRARY})
|
||||
endif()
|
||||
|
||||
install(TARGETS ${PROJECT_NAME}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} # static lib
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} # binaries
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} # shared lib
|
||||
FRAMEWORK DESTINATION ${CMAKE_INSTALL_LIBDIR} # for mac
|
||||
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME} # headers for mac (note the different component -> different package)
|
||||
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} # headers
|
||||
)
|
||||
142
src/sc_main.cpp
Normal file
142
src/sc_main.cpp
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (c) 2019 -2021 MINRES Technolgies GmbH
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "CLIParser.h"
|
||||
#include <iss/log_categories.h>
|
||||
|
||||
#include <scc/configurable_tracer.h>
|
||||
#include <scc/configurer.h>
|
||||
#include <scc/hierarchy_dumper.h>
|
||||
#include <scc/report.h>
|
||||
#include <scc/scv/scv_tr_db.h>
|
||||
#include <scc/tracer.h>
|
||||
#include <scc/perf_estimator.h>
|
||||
#ifdef WITH_LLVM
|
||||
#include <iss/llvm/jit_helper.h>
|
||||
#endif
|
||||
|
||||
#include <boost/program_options.hpp>
|
||||
#include "vp/tb.h"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#ifdef ERROR
|
||||
#undef ERROR
|
||||
#endif
|
||||
|
||||
const std::string core_path{"tb.top.core_complex"};
|
||||
|
||||
using namespace sysc;
|
||||
using namespace sc_core;
|
||||
namespace po = boost::program_options;
|
||||
|
||||
namespace {
|
||||
const size_t ERRORR_IN_COMMAND_LINE = 1;
|
||||
const size_t SUCCESS = 0;
|
||||
} // namespace
|
||||
|
||||
int sc_main(int argc, char *argv[]) {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// SystemC >=2.2 got picky about multiple drivers so disable check
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
sc_report_handler::set_actions(SC_ID_MORE_THAN_ONE_SIGNAL_DRIVER_, SC_DO_NOTHING);
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// CLI argument parsing & logging setup
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
CLIParser parser(argc, argv);
|
||||
if (!parser.is_valid()) return ERRORR_IN_COMMAND_LINE;
|
||||
scc::stream_redirection cout_redir(std::cout, scc::log::INFO);
|
||||
scc::stream_redirection cerr_redir(std::cerr, scc::log::ERROR);
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// set up infrastructure
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
#ifdef WITH_LLVM
|
||||
iss::init_jit_debug(argc, argv);
|
||||
#endif
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// create the performance estimation module
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
scc::perf_estimator estimator;
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// set up configuration
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
scc::configurer cfg(parser.get<std::string>("config-file"));
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// set up tracing & transaction recording
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::unique_ptr<scc::configurable_tracer> tracer;
|
||||
if( auto trace_level = parser.get<unsigned>("trace-level")) {
|
||||
auto file_name = parser.get<std::string>("trace-file");
|
||||
auto enable_sig_trace = (trace_level&0x1) != 0;// bit0 enables sig trace
|
||||
auto tx_trace_type = static_cast<scc::tracer::file_type>(trace_level >> 1); // bit3-bit1 define the kind of transaction trace
|
||||
auto trace_default_on = parser.is_set("trace-default-on");
|
||||
cfg.set_value("$$$scc_tracer$$$.tx_trace_type", static_cast<unsigned>(scc::tracer::file_type::FTR));
|
||||
cfg.set_value("$$$scc_tracer$$$.sig_trace_type", static_cast<unsigned>(scc::tracer::file_type::SC_VCD));
|
||||
tracer = scc::make_unique<scc::configurable_tracer>(file_name, tx_trace_type, enable_sig_trace, trace_default_on);
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// instantiate top level
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
auto i_system = scc::make_unique<tgc_vp::tb>("tb");
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// add non-implemented 'enableTracing' properties
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
if(tracer) tracer->add_control();
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// dump configuration if requested
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
if (parser.get<std::string>("dump-config").size() > 0) {
|
||||
std::ofstream of{parser.get<std::string>("dump-config")};
|
||||
if (of.is_open()) cfg.dump_configuration(of, true);
|
||||
}
|
||||
cfg.configure();
|
||||
std::unique_ptr<scc::hierarchy_dumper> dumper;
|
||||
if(parser.is_set("dump-structure"))
|
||||
dumper.reset(new scc::hierarchy_dumper(parser.get<std::string>("dump-structure"), scc::hierarchy_dumper::D3JSON));
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// overwrite config with command line settings
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
cfg.set_value(core_path + ".gdb_server_port", parser.get<unsigned short>("gdb-port"));
|
||||
cfg.set_value(core_path + ".dump_ir", parser.is_set("dump-ir"));
|
||||
cfg.set_value(core_path + ".backend", parser.get<std::string>("backend"));
|
||||
cfg.set_value(core_path + ".core_type", parser.get<std::string>("isa"));
|
||||
if(parser.is_set("plugin")){
|
||||
auto plugins = util::join(parser.get<std::vector<std::string>>("plugin"),",");
|
||||
cfg.set_value(core_path + ".plugins", plugins);
|
||||
}
|
||||
if (parser.is_set("elf")) cfg.set_value(core_path + ".elf_file", parser.get<std::string>("elf"));
|
||||
if (parser.is_set("quantum"))
|
||||
tlm::tlm_global_quantum::instance().set(sc_core::sc_time(parser.get<unsigned>("quantum"), sc_core::SC_NS));
|
||||
if (parser.is_set("reset")) {
|
||||
auto str = parser.get<std::string>("reset");
|
||||
uint64_t start_address = str.find("0x") == 0 ? std::stoull(str.substr(2), nullptr, 16) : std::stoull(str, nullptr, 10);
|
||||
cfg.set_value(core_path + ".reset_address", start_address);
|
||||
}
|
||||
if (parser.is_set("disass")) {
|
||||
cfg.set_value(core_path + ".enable_disass", true);
|
||||
LOGGER(disass)::reporting_level() = logging::INFO;
|
||||
auto file_name = parser.get<std::string>("disass");
|
||||
if (file_name.length() > 0) {
|
||||
LOG_OUTPUT(disass)::stream() = fopen(file_name.c_str(), "w");
|
||||
LOGGER(disass)::print_time() = false;
|
||||
LOGGER(disass)::print_severity() = false;
|
||||
}
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// run simulation
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
try {
|
||||
if (parser.is_set("max_time")) {
|
||||
sc_core::sc_start(scc::parse_from_string(parser.get<std::string>("max_time")));
|
||||
} else
|
||||
sc_core::sc_start();
|
||||
if (!sc_core::sc_end_of_simulation_invoked()) sc_core::sc_stop();
|
||||
} catch (sc_core::sc_report &rep) {
|
||||
sc_core::sc_report_handler::get_handler()(rep, sc_core::SC_DISPLAY | sc_core::SC_STOP);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
21
src/vp/gen/PipelinedMemoryBusToApbBridge.h
Normal file
21
src/vp/gen/PipelinedMemoryBusToApbBridge.h
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (c) 2023 - 2024 MINRES Technologies GmbH
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Generated at 2024-02-08 14:41:56 UTC
|
||||
* by peakrdl_mnrs version 1.2.2
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// need double braces, see https://stackoverflow.com/questions/6893700/how-to-construct-stdarray-object-with-initializer-list#6894191
|
||||
const std::array<scc::target_memory_map_entry<scc::LT>, 6> PipelinedMemoryBusToApbBridge_map = {{
|
||||
{ gpio0.socket, 0x0, 0xc },
|
||||
{ uart0.socket, 0x1000, 0x14 },
|
||||
{ timer0.socket, 0x20000, 0x1c },
|
||||
{ aclint.socket, 0x30000, 0xc000 },
|
||||
{ irq_ctrl.socket, 0x40000, 0x8 },
|
||||
{ qspi.socket, 0x50000, 0x5c },
|
||||
//{ bootloader.socket, 0x80000, 0x400 },
|
||||
}} ;
|
||||
26
src/vp/gen/platform_mmap.h
Normal file
26
src/vp/gen/platform_mmap.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2019 -2021 MINRES Technolgies GmbH
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef _PLATFORM_MMAP_H_
|
||||
#define _PLATFORM_MMAP_H_
|
||||
// need double braces, see
|
||||
// https://stackoverflow.com/questions/6893700/how-to-construct-stdarray-object-with-initializer-list#6894191
|
||||
const std::array<scc::target_memory_map_entry<scc::LT>, 13> platfrom_mmap = {{
|
||||
{clint.socket, 0x2000000, 0xc000},
|
||||
{plic.socket, 0xc000000, 0x200008},
|
||||
{aon.socket, 0x10000000, 0x150},
|
||||
{prci.socket, 0x10008000, 0x14},
|
||||
{gpio0.socket, 0x10012000, 0x44},
|
||||
{uart0.socket, 0x10013000, 0x1c},
|
||||
{qspi0.socket, 0x10014000, 0x78},
|
||||
{pwm0.socket, 0x10015000, 0x30},
|
||||
{uart1.socket, 0x10023000, 0x1c},
|
||||
{qspi1.socket, 0x10024000, 0x78},
|
||||
{pwm1.socket, 0x10025000, 0x30},
|
||||
{qspi2.socket, 0x10034000, 0x78},
|
||||
{pwm2.socket, 0x10035000, 0x30},
|
||||
}};
|
||||
|
||||
#endif /* _PLATFORM_MMAP_H_ */
|
||||
25
src/vp/platform.rdl
Normal file
25
src/vp/platform.rdl
Normal file
@@ -0,0 +1,25 @@
|
||||
`include "gpio.rdl"
|
||||
`include "uart.rdl"
|
||||
`include "spi.rdl"
|
||||
`include "pwm.rdl"
|
||||
`include "plic.rdl"
|
||||
`include "aon.rdl"
|
||||
`include "prci.rdl"
|
||||
`include "clint.rdl"
|
||||
|
||||
addrmap e300_plat_t {
|
||||
lsb0;
|
||||
clint_regs clint @0x02000000;
|
||||
plic_regs plic @0x0C000000;
|
||||
aon_regs aon @0x10000000;
|
||||
prci_regs prci @0x10008000;
|
||||
gpio_regs gpio0 @0x10012000;
|
||||
uart_regs uart0 @0x10013000;
|
||||
spi_regs qspi0 @0x10014000;
|
||||
pwm_regs pwm0 @0x10015000;
|
||||
uart_regs uart1 @0x10023000;
|
||||
spi_regs qspi1 @0x10024000;
|
||||
pwm_regs pwm1 @0x10025000;
|
||||
spi_regs qspi2 @0x10034000;
|
||||
pwm_regs pwm2 @0x10035000;
|
||||
} e300_plat;
|
||||
27
src/vp/rst_gen.h
Normal file
27
src/vp/rst_gen.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2019 -2021 MINRES Technolgies GmbH
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <systemc>
|
||||
namespace tgc_vp {
|
||||
|
||||
class rst_gen : public sc_core::sc_module {
|
||||
SC_HAS_PROCESS(rst_gen);
|
||||
public:
|
||||
rst_gen(sc_core::sc_module_name const& nm) {
|
||||
SC_THREAD(run);
|
||||
}
|
||||
sc_core::sc_out<bool> rst_n{"rst_n"};
|
||||
private:
|
||||
void run(){
|
||||
rst_n.write(false);
|
||||
wait(100_ns);
|
||||
rst_n.write(true);
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace tgc_vp */
|
||||
96
src/vp/system.cpp
Normal file
96
src/vp/system.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 2019 -2021 MINRES Technolgies GmbH
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "../vp/system.h"
|
||||
|
||||
#include "minres/timer.h"
|
||||
#include "minres/uart.h"
|
||||
#include "scc/utilities.h"
|
||||
|
||||
namespace tgc_vp {
|
||||
using namespace sc_core;
|
||||
using namespace vpvper::minres;
|
||||
using namespace sysc::tgfs;
|
||||
|
||||
system::system(sc_core::sc_module_name nm)
|
||||
: sc_core::sc_module(nm)
|
||||
, NAMED(ahb_router, 3, 2)
|
||||
, NAMED(apbBridge, PipelinedMemoryBusToApbBridge_map.size(), 1){
|
||||
core_complex.ibus(ahb_router.target[0]);
|
||||
core_complex.dbus(ahb_router.target[1]);
|
||||
|
||||
ahb_router.initiator.at(0)(qspi.xip_sck);
|
||||
ahb_router.set_target_range(0, 0xE0000000, 16_MB);
|
||||
ahb_router.initiator.at(1)(mem_ram.target);
|
||||
ahb_router.set_target_range(1, 0x80000000, 32_kB);
|
||||
ahb_router.initiator.at(2)(apbBridge.target[0]);
|
||||
ahb_router.set_target_range(2, 0xF0000000, 256_MB);
|
||||
|
||||
size_t i = 0;
|
||||
for (const auto &e : PipelinedMemoryBusToApbBridge_map) {
|
||||
apbBridge.initiator.at(i)(e.target);
|
||||
apbBridge.set_target_range(i, e.start, e.size);
|
||||
i++;
|
||||
}
|
||||
|
||||
gpio0.clk_i(clk_i);
|
||||
uart0.clk_i(clk_i);
|
||||
timer0.clk_i(clk_i);
|
||||
aclint.clk_i(clk_i);
|
||||
irq_ctrl.clk_i(clk_i);
|
||||
qspi.clk_i(clk_i);
|
||||
core_complex.clk_i(clk_i);
|
||||
//mem_ram.clk_i(clk_i);
|
||||
|
||||
gpio0.rst_i(rst_s);
|
||||
uart0.rst_i(rst_s);
|
||||
timer0.rst_i(rst_s);
|
||||
aclint.rst_i(rst_s);
|
||||
irq_ctrl.rst_i(rst_s);
|
||||
qspi.rst_i(rst_s);
|
||||
core_complex.rst_i(rst_s);
|
||||
|
||||
aclint.mtime_int_o(mtime_int_s);
|
||||
aclint.msip_int_o(msip_int_s);
|
||||
irq_ctrl.irq_o(core_int_s);
|
||||
irq_ctrl.pending_irq_i(irq_int_s);
|
||||
|
||||
uart0.irq_o(irq_int_s[0]);
|
||||
timer0.interrupt_o[0](irq_int_s[1]);
|
||||
timer0.interrupt_o[1](irq_int_s[2]);
|
||||
qspi.irq_o(irq_int_s[3]);
|
||||
|
||||
core_complex.timer_irq_i(mtime_int_s);
|
||||
core_complex.ext_irq_i(core_int_s);
|
||||
core_complex.local_irq_i(local_int_s);
|
||||
core_complex.sw_irq_i(msip_int_s);
|
||||
|
||||
gpio0.pins_i(pins_i);
|
||||
gpio0.pins_o(pins_o);
|
||||
gpio0.oe_o(pins_oe_o);
|
||||
|
||||
uart0.tx_o(uart0_tx_o);
|
||||
uart0.rx_i(uart0_rx_i);
|
||||
|
||||
timer0.clear_i(t0_clear_i);
|
||||
timer0.tick_i(t0_tick_i);
|
||||
|
||||
qspi.ssclk_o(ssclk_o);
|
||||
qspi.dq_o(dq_o);
|
||||
qspi.dq_i(dq_i);
|
||||
qspi.oe_o(dq_oe_o);
|
||||
|
||||
SC_METHOD(gen_reset);
|
||||
sensitive << erst_n;
|
||||
}
|
||||
void system::gen_reset(){
|
||||
if(erst_n.read())
|
||||
rst_s = 0;
|
||||
else rst_s = 1;
|
||||
}
|
||||
|
||||
|
||||
} /* namespace sysc */
|
||||
78
src/vp/system.h
Normal file
78
src/vp/system.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2019 -2021 MINRES Technolgies GmbH
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _PLATFORM_H_
|
||||
#define _PLATFORM_H_
|
||||
|
||||
#include "minres/irq.h"
|
||||
#include "minres/timer.h"
|
||||
#include <minres/aclint.h>
|
||||
#include <minres/gpio.h>
|
||||
#include <minres/qspi.h>
|
||||
#include <sysc/communication/sc_clock.h>
|
||||
#include <sysc/communication/sc_signal_ports.h>
|
||||
#include <sysc/core_complex.h>
|
||||
#include <minres/uart.h>
|
||||
#include <cci_configuration>
|
||||
#include <scc/memory.h>
|
||||
#include <scc/router.h>
|
||||
#include <scc/utilities.h>
|
||||
#include <sysc/kernel/sc_time.h>
|
||||
#include <sysc/utils/sc_vector.h>
|
||||
#include <tlm/scc/tlm_signal_sockets.h>
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <sysc/kernel/sc_module.h>
|
||||
|
||||
namespace tgc_vp {
|
||||
|
||||
class system : public sc_core::sc_module {
|
||||
public:
|
||||
SC_HAS_PROCESS(system);// NOLINT
|
||||
|
||||
sc_core::sc_vector<sc_core::sc_out<bool>> pins_o{"pins_o",32};
|
||||
sc_core::sc_vector<sc_core::sc_out<bool>> pins_oe_o{"pins_oe_o", 32};
|
||||
sc_core::sc_vector<sc_core::sc_in<bool>> pins_i{"pins_i", 32};
|
||||
sc_core::sc_out<bool> uart0_tx_o {"uart0_tx_o"};
|
||||
sc_core::sc_in<bool> uart0_rx_i {"uart0_rx_i"};
|
||||
sc_core::sc_vector<sc_core::sc_in<bool>> t0_clear_i {"t0_clear_i", vpvper::minres::timer::CLEAR_CNT};
|
||||
sc_core::sc_vector<sc_core::sc_in<bool>> t0_tick_i {"t0_tick_i", vpvper::minres::timer::TICK_CNT-1};
|
||||
sc_core::sc_out<bool> ssclk_o{"ssclk_o"};
|
||||
sc_core::sc_vector<sc_core::sc_out<bool>> dq_o{"dq_o", 4};
|
||||
sc_core::sc_vector<sc_core::sc_out<bool>> dq_oe_o{"dq_oe_o", 4};
|
||||
sc_core::sc_vector<sc_core::sc_in<bool>> dq_i{"dq_i", 4};
|
||||
|
||||
sc_core::sc_in<sc_core::sc_time> clk_i{"clk_i"};
|
||||
|
||||
sc_core::sc_in<bool> erst_n{"erst_n"};
|
||||
|
||||
system(sc_core::sc_module_name nm);
|
||||
|
||||
private:
|
||||
sysc::tgfs::core_complex core_complex{"core_complex"};
|
||||
scc::router<> ahb_router, apbBridge;
|
||||
vpvper::minres::gpio_tl gpio0{"gpio0"};
|
||||
vpvper::minres::uart_tl uart0{"uart0"};
|
||||
vpvper::minres::timer_tl timer0{"timer0"};
|
||||
vpvper::minres::aclint_tl aclint{"aclint"};
|
||||
vpvper::minres::irq_tl irq_ctrl{"irq_ctrl"};
|
||||
vpvper::minres::qspi_tl qspi{"qspi"};
|
||||
|
||||
//scc::memory<1_kB, scc::LT> bootloader{"bootloader"};
|
||||
scc::memory<32_kB, scc::LT> mem_ram {"mem_ram"};
|
||||
|
||||
sc_core::sc_signal<bool, sc_core::SC_MANY_WRITERS> rst_s{"rst_s"}, mtime_int_s{"mtime_int_s"}, msip_int_s{"msip_int_s"};
|
||||
|
||||
sc_core::sc_vector<sc_core::sc_signal<bool, sc_core::SC_MANY_WRITERS>> irq_int_s{"irq_int_s", 32}, local_int_s{"local_int_s", 16};
|
||||
sc_core::sc_signal<bool, sc_core::SC_MANY_WRITERS> core_int_s{"core_int_s"};
|
||||
|
||||
void gen_reset();
|
||||
#include "../vp/gen/PipelinedMemoryBusToApbBridge.h"
|
||||
};
|
||||
|
||||
} /* namespace sysc */
|
||||
|
||||
#endif /* _PLATFORM_H_ */
|
||||
30
src/vp/tb.cpp
Normal file
30
src/vp/tb.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2019 -2021 MINRES Technolgies GmbH
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "../vp/tb.h"
|
||||
|
||||
#include <sysc/kernel/sc_time.h>
|
||||
namespace tgc_vp {
|
||||
|
||||
SC_HAS_PROCESS(tb);
|
||||
tb::tb(const sc_core::sc_module_name &nm): sc_core::sc_module(nm) {
|
||||
top.erst_n(rst_n);
|
||||
rst_gen.rst_n(rst_n);
|
||||
top.pins_o(pins_o);
|
||||
top.pins_i(pins_i);
|
||||
top.pins_oe_o(pins_oe_o);
|
||||
top.uart0_rx_i(uart0_rx_i);
|
||||
top.uart0_tx_o(uart0_tx_o);
|
||||
top.t0_clear_i(t0_clear_i);
|
||||
top.t0_tick_i(t0_tick_i);
|
||||
top.ssclk_o(ssclk_o);
|
||||
top.dq_o(dq_o);
|
||||
top.dq_i(dq_i);
|
||||
top.dq_oe_o(dq_oe_o);
|
||||
top.clk_i(clk_i);
|
||||
clk_i = 10_ns;
|
||||
}
|
||||
}
|
||||
39
src/vp/tb.h
Normal file
39
src/vp/tb.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2019 -2021 MINRES Technolgies GmbH
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef SRC_VP_TB_H_
|
||||
#define SRC_VP_TB_H_
|
||||
|
||||
#include <generic/terminal.h>
|
||||
#include <systemc>
|
||||
|
||||
#include "../vp/rst_gen.h"
|
||||
#include "../vp/system.h"
|
||||
namespace tgc_vp {
|
||||
|
||||
class tb : public sc_core::sc_module {
|
||||
public:
|
||||
tb(sc_core::sc_module_name const& nm);
|
||||
tgc_vp::system top{"top"};
|
||||
tgc_vp::rst_gen rst_gen{"rst_gen"};
|
||||
sc_core::sc_signal<bool> rst_n{"rst_n"};
|
||||
sc_core::sc_vector<sc_core::sc_signal<bool>> pins_o{"pins_o",32};
|
||||
sc_core::sc_vector<sc_core::sc_signal<bool>> pins_oe_o{"pins_oe_o", 32};
|
||||
sc_core::sc_vector<sc_core::sc_signal<bool>> pins_i{"pins_i", 32};
|
||||
sc_core::sc_signal<bool> uart0_tx_o {"uart0_tx_o"};
|
||||
sc_core::sc_signal<bool> uart0_rx_i {"uart0_rx_i"};
|
||||
sc_core::sc_vector<sc_core::sc_signal<bool>> t0_clear_i {"t0_clear_i", vpvper::minres::timer::CLEAR_CNT};
|
||||
sc_core::sc_vector<sc_core::sc_signal<bool>> t0_tick_i {"t0_tick_i", vpvper::minres::timer::TICK_CNT-1};
|
||||
sc_core::sc_signal<bool> ssclk_o{"ssclk_o"};
|
||||
sc_core::sc_vector<sc_core::sc_signal<bool>> dq_o{"dq_o", 4};
|
||||
sc_core::sc_vector<sc_core::sc_signal<bool>> dq_oe_o{"dq_oe_o", 4};
|
||||
sc_core::sc_vector<sc_core::sc_signal<bool>> dq_i{"dq_i", 4};
|
||||
sc_core::sc_signal<sc_core::sc_time> clk_i{"clk_i"};
|
||||
};
|
||||
|
||||
} /* namespace tgc_vp */
|
||||
|
||||
#endif /* SRC_VP_TB_H_ */
|
||||
Reference in New Issue
Block a user