Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into map_v2
Browse files Browse the repository at this point in the history
  • Loading branch information
klingaard committed Nov 14, 2024
2 parents fdcc927 + 05ba853 commit f1d0a5c
Show file tree
Hide file tree
Showing 13 changed files with 215 additions and 90 deletions.
3 changes: 2 additions & 1 deletion sparta/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ build*
[Ff]ast[Dd]ebug*
cmake-build-*
*~
compile_commands.json
compile_commands.json
.vscode
8 changes: 7 additions & 1 deletion sparta/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,13 @@ if (ENABLE_SANITIZERS)
endif ()

set(CMAKE_CXX_FLAGS_PROFILE "-O3 -pg -g")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g3")
if(DEFINED SPARTA_CXX_FLAGS_DEBUG AND SPARTA_CXX_FLAGS_DEBUG)
set(CMAKE_CXX_FLAGS_DEBUG "${SPARTA_CXX_FLAGS_DEBUG}")
message(STATUS "Using Sparta custom debug flags: ${CMAKE_CXX_FLAGS_DEBUG}")
else()
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g3")
message(STATUS "Using Sparta default debug flags: ${CMAKE_CXX_FLAGS_DEBUG}")
endif()

#
# If we're using CONDA, we might be using the one suggested for
Expand Down
29 changes: 29 additions & 0 deletions sparta/sparta/events/EventNode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,42 @@ namespace sparta
//! Get the scheduleable associated with this event node
virtual Scheduleable & getScheduleable() = 0;

/**
* \brief Turn on/off auto precedence for this EvendNode
* \param participate Set to true [default] if the EventNode is to
* participate in auto precedence establishment
* in sparta::Unit
*
* In sparta::Unit, registered sparta::Event types and Ports will
* have auto precedence established between them if the user
* of sparta::Unit allows it to do so. However, this might not
* be desired for some Events that are created by the modeler
* and internally bound before the sparta::Unit performs this
* setup. Calling this method with participate set to false,
* will prevent the assertion that the EventNode is be being
* registered after port binding.
*/
virtual void participateInAutoPrecedence(bool participate) {
participate_in_auto_precedence_ = participate;
}

//! \brief Does this EventNode participate in auto-precedence
//! establishment by sparta::Unit?
//! \return true if so, false otherwise
virtual bool doesParticipateInAutoPrecedence() const {
return participate_in_auto_precedence_;
}

private:

//! Make sure the parent is an EventNodeSet
void ensureParentIsEventSet_(sparta::TreeNode* parent);

//! Scheduling phase of this node
const sparta::SchedulingPhase sched_phase_;

//! Does this EventNode participate in auto precedence?
bool participate_in_auto_precedence_ = true;
};
}

Expand Down
54 changes: 53 additions & 1 deletion sparta/sparta/functional/Register.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1507,6 +1507,48 @@ class Register : public RegisterBase
return ss.str();
}

/*!
* \brief Index of read/write access within register
*/
typedef RegisterBase::index_type index_type;

/*!
* \brief Read value directly from the Register's backing store
* \note This is intentionally hiding the dmiRead() from the base
* class so we don't have to go through the dmiRead_() virtual method.
*/
template <typename T>
inline T dmiRead(index_type idx = 0) const
{
T res;
dmiReadImpl_(&res, sizeof(res), sizeof(res) * idx);
return res;
}

/*!
* \brief Write a value directly to this Register's backing store
* \note No masking, boundary checkor or notification is performed
* \note This is intentionally hiding the dmiWrite() from the base
* class so we don't have to go through the dmiWrite_() virtual method.
*/
template <typename T>
inline void dmiWrite(T val, index_type idx = 0)
{
dmiWriteImpl_(&val, sizeof(val), sizeof(val) * idx);
}

/*!
* \brief Write a value into this register without it being affected by the write-mask
* \warning This ignores read-only fields
* \note This is intentionally hiding the writeUnmasked() from the base
* class so we don't have to go through the dmiWriteImpl_() virtual method.
*/
template <typename T>
inline void writeUnmasked(T val, index_type idx = 0)
{
dmiWriteImpl_(&val, sizeof(T), idx);
}

private:
/*!
* \brief Discover and store the raw location of this Register's data
Expand Down Expand Up @@ -1536,7 +1578,7 @@ class Register : public RegisterBase

void dmiRead_(void *buf, size_t size, size_t offset = 0) const override final
{
memcpy(buf, raw_data_ptr_ + offset, size);
dmiReadImpl_(buf, size, offset);
}

void write_(const void *buf, size_t size, size_t offset=0) override final
Expand All @@ -1559,6 +1601,16 @@ class Register : public RegisterBase
}

void dmiWrite_(const void *buf, size_t size, size_t offset = 0) override final
{
dmiWriteImpl_(buf, size, offset);
}

inline void dmiReadImpl_(void *buf, size_t size, size_t offset = 0) const
{
memcpy(buf, raw_data_ptr_ + offset, size);
}

inline void dmiWriteImpl_(const void *buf, size_t size, size_t offset = 0)
{
memcpy(raw_data_ptr_ + offset, buf, size);
dview_.getLine()->flagDirty();
Expand Down
19 changes: 11 additions & 8 deletions sparta/sparta/functional/RegisterSet.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -480,8 +480,9 @@ class RegisterSet : public TreeNode
const RegisterBase::Definition *defs,
const RegisterProxyBase::Definition *proxy_defs,
CurrentBankFunction cbfxn,
RegisterTypeTag<RegisterT> tag)
: TreeNode("regs",
RegisterTypeTag<RegisterT> tag,
const std::string& name = "regs")
: TreeNode(name,
TreeNode::GROUP_NAME_BUILTIN,
TreeNode::GROUP_IDX_NONE,
"Register set")
Expand Down Expand Up @@ -530,8 +531,9 @@ class RegisterSet : public TreeNode
template <typename RegisterT>
RegisterSet(TreeNode *parent,
const RegisterBase::Definition *defs,
RegisterTypeTag<RegisterT> tag)
: RegisterSet(parent, defs, nullptr, nullptr, tag)
RegisterTypeTag<RegisterT> tag,
const std::string& name = "regs")
: RegisterSet(parent, defs, nullptr, nullptr, tag, name)
{
// Handled in delegated consturctor
}
Expand All @@ -541,18 +543,19 @@ class RegisterSet : public TreeNode
create(TreeNode *parent,
const RegisterBase::Definition *defs,
const RegisterProxyBase::Definition *proxy_defs,
CurrentBankFunction cbfxn)
CurrentBankFunction cbfxn,
const std::string& name = "regs")
{
return std::unique_ptr<RegisterSet>(new RegisterSet(
parent, defs, proxy_defs, cbfxn, RegisterTypeTag<RegisterT>()));
parent, defs, proxy_defs, cbfxn, RegisterTypeTag<RegisterT>(), name));
}

template <typename RegisterT = Register>
static std::unique_ptr<RegisterSet>
create(TreeNode *parent, const RegisterBase::Definition *defs)
create(TreeNode *parent, const RegisterBase::Definition *defs, const std::string& name = "regs")
{
return std::unique_ptr<RegisterSet>(new RegisterSet(
parent, defs, RegisterTypeTag<RegisterT>()));
parent, defs, RegisterTypeTag<RegisterT>(), name));
}

/*!
Expand Down
1 change: 1 addition & 0 deletions sparta/sparta/kernel/DAG.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ namespace sparta
VertexMap gops_;
bool finalized_ = false;
sparta::Scheduler* my_scheduler_ = nullptr;
const log::MessageSource debug_logger_;
};//End class DAG


Expand Down
116 changes: 56 additions & 60 deletions sparta/sparta/parsers/ConfigEmitterYAML.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "sparta/simulation/Parameter.hpp"
#include "sparta/app/SimulationInfo.hpp"
#include "sparta/simulation/TreeNodePrivateAttorney.hpp"
#include "sparta/simulation/ParameterTree.hpp"

namespace YP = YAML; // Prevent collision with YAML class in ConfigEmitter namespace.

Expand Down Expand Up @@ -80,6 +81,7 @@ class YAML : public ConfigEmitter
* \post emitter_ will be nullptr
*/
void addParameters(TreeNode* device_tree,
const ParameterTree* extensions_ptree,
bool verbose=false)
{
sparta_assert(emitter_ == nullptr);
Expand All @@ -102,52 +104,26 @@ class YAML : public ConfigEmitter

*emitter_ << YP::BeginDoc;
sparta_assert(emitter_->good());
handleNode_(device_tree, verbose); // Recurse

if (!tree_node_extensions_.empty()) {
for (auto & ext_info : tree_node_extensions_) {
TreeNode * tn = ext_info.first;
std::vector<std::pair<std::string, TreeNode::ExtensionsBase*>> & node_extensions =
ext_info.second;

*emitter_ << YP::BeginMap;
*emitter_ << YP::Key << tn->getLocation();
*emitter_ << YP::Value;
*emitter_ << YP::BeginMap;

for (auto & node_extension : node_extensions) {
*emitter_ << YP::Key << ("extension." + node_extension.first);
*emitter_ << YP::Value;
*emitter_ << YP::BeginMap;

TreeNode::ExtensionsBase * ext_base = node_extension.second;
ParameterSet * params = ext_base->getYamlOnlyParameters();
auto param_names = params->getNames();
for (const auto & param_name : param_names) {
*emitter_ << YP::Key << param_name;
*emitter_ << YP::Value // << YP::PadToColumn(50)
<< params->getParameter(param_name)->getValueAsString();
std::stringstream tags;
params->getParameter(param_name)->stringizeTags(tags);
*emitter_ << YP::Comment(tags.str());
}

params = ext_base->getParameters();
param_names = params->getNames();
for (const auto & param_name : param_names) {
*emitter_ << YP::Key << param_name;
*emitter_ << YP::Value // << YP::PadToColumn(50)
<< params->getParameter(param_name)->getValueAsString();
std::stringstream tags;
params->getParameter(param_name)->stringizeTags(tags);
*emitter_ << YP::Comment(tags.str());
}

*emitter_ << YP::EndMap;
}
*emitter_ << YP::EndMap;
*emitter_ << YP::EndMap;
}
handleNode_(device_tree, verbose);

if (extensions_ptree) {
// Note we use the ParameterTree to get the tree node extensions instead
// of the device tree since using the device tree might serialize an extension
// defn of:
//
// top.cpu.core*.extension.core_extensions:
// name: value
// name: value
//
// As:
//
// top.cpu.core0.extension.core_extensions:
// name: value
// name: value
//
// But the ParameterTree retains the wildcards in the path.
handleNode_(extensions_ptree->getRoot());
}

*emitter_ << YP::EndDoc;
Expand All @@ -172,6 +148,41 @@ class YAML : public ConfigEmitter


private:
/*!
* \brief Recursively write the TreeNode extensions defns to YAML
*/
void handleNode_(const ParameterTree::Node* subtree)
{
sparta_assert(subtree);
sparta_assert(emitter_ != nullptr);

if (subtree->getName() == "extension") {
auto location_key = subtree->getParent()->getPath();
*emitter_ << YP::BeginMap;
*emitter_ << YP::Key << location_key;
*emitter_ << YP::Value;
*emitter_ << YP::BeginMap;

for (const auto child : subtree->getChildren()) {
auto extension_name = child->getName();
*emitter_ << YP::Key << ("extension." + extension_name);
*emitter_ << YP::Value;
*emitter_ << YP::BeginMap;
for (const auto param : child->getChildren()) {
*emitter_ << YP::Key << param->getName();
*emitter_ << YP::Value << param->getValue();
}
*emitter_ << YP::EndMap;
}

*emitter_ << YP::EndMap;
*emitter_ << YP::EndMap;
} else {
for (const auto child : subtree->getChildren()) {
handleNode_(child);
}
}
}

/*!
* \brief Render the content of this node as a sequence of YAML
Expand All @@ -186,15 +197,6 @@ class YAML : public ConfigEmitter
sparta_assert(subtree);
sparta_assert(emitter_ != nullptr);

const auto & extension_names = subtree->getAllExtensionNames();
for (const auto & ext_name : extension_names) {
auto extension = subtree->getExtension(ext_name);
if (extension) {
tree_node_extensions_[subtree].emplace_back(
std::make_pair(ext_name, subtree->getExtension(ext_name)));
}
}

// Print parameter value if this node is a parameter
const ParameterBase* pb = dynamic_cast<const ParameterBase*>(subtree);
if(pb){
Expand Down Expand Up @@ -396,12 +398,6 @@ class YAML : public ConfigEmitter
*/
const bool show_param_descs_;

/*!
* \brief Mapping from tree nodes to their named extensions, if any
*/
std::unordered_map<TreeNode*,
std::vector<std::pair<std::string, TreeNode::ExtensionsBase*>>> tree_node_extensions_;

}; // class YAML

} // namespace ConfigEmitter
Expand Down
5 changes: 5 additions & 0 deletions sparta/sparta/simulation/Unit.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,11 @@ namespace sparta {

for(auto & event_node : unit_event_set_.getEvents(sparta::SchedulingPhase::Tick))
{
// This event does not participate in auto precedence.
if(!event_node->doesParticipateInAutoPrecedence()) {
continue;
}

// Go through all of the registered InPorts and set these
// ports to precede any events that are on the Tick phase.
// This is for 0-cycle precedence only.
Expand Down
Loading

0 comments on commit f1d0a5c

Please sign in to comment.