Skip to content

Commit f1d0a5c

Browse files
committed
Merge remote-tracking branch 'origin/master' into map_v2
2 parents fdcc927 + 05ba853 commit f1d0a5c

13 files changed

+215
-90
lines changed

sparta/.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ build*
1111
[Ff]ast[Dd]ebug*
1212
cmake-build-*
1313
*~
14-
compile_commands.json
14+
compile_commands.json
15+
.vscode

sparta/CMakeLists.txt

+7-1
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,13 @@ if (ENABLE_SANITIZERS)
154154
endif ()
155155

156156
set(CMAKE_CXX_FLAGS_PROFILE "-O3 -pg -g")
157-
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g3")
157+
if(DEFINED SPARTA_CXX_FLAGS_DEBUG AND SPARTA_CXX_FLAGS_DEBUG)
158+
set(CMAKE_CXX_FLAGS_DEBUG "${SPARTA_CXX_FLAGS_DEBUG}")
159+
message(STATUS "Using Sparta custom debug flags: ${CMAKE_CXX_FLAGS_DEBUG}")
160+
else()
161+
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g3")
162+
message(STATUS "Using Sparta default debug flags: ${CMAKE_CXX_FLAGS_DEBUG}")
163+
endif()
158164

159165
#
160166
# If we're using CONDA, we might be using the one suggested for

sparta/sparta/events/EventNode.hpp

+29
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,42 @@ namespace sparta
9797
//! Get the scheduleable associated with this event node
9898
virtual Scheduleable & getScheduleable() = 0;
9999

100+
/**
101+
* \brief Turn on/off auto precedence for this EvendNode
102+
* \param participate Set to true [default] if the EventNode is to
103+
* participate in auto precedence establishment
104+
* in sparta::Unit
105+
*
106+
* In sparta::Unit, registered sparta::Event types and Ports will
107+
* have auto precedence established between them if the user
108+
* of sparta::Unit allows it to do so. However, this might not
109+
* be desired for some Events that are created by the modeler
110+
* and internally bound before the sparta::Unit performs this
111+
* setup. Calling this method with participate set to false,
112+
* will prevent the assertion that the EventNode is be being
113+
* registered after port binding.
114+
*/
115+
virtual void participateInAutoPrecedence(bool participate) {
116+
participate_in_auto_precedence_ = participate;
117+
}
118+
119+
//! \brief Does this EventNode participate in auto-precedence
120+
//! establishment by sparta::Unit?
121+
//! \return true if so, false otherwise
122+
virtual bool doesParticipateInAutoPrecedence() const {
123+
return participate_in_auto_precedence_;
124+
}
125+
100126
private:
101127

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

105131
//! Scheduling phase of this node
106132
const sparta::SchedulingPhase sched_phase_;
133+
134+
//! Does this EventNode participate in auto precedence?
135+
bool participate_in_auto_precedence_ = true;
107136
};
108137
}
109138

sparta/sparta/functional/Register.hpp

+53-1
Original file line numberDiff line numberDiff line change
@@ -1507,6 +1507,48 @@ class Register : public RegisterBase
15071507
return ss.str();
15081508
}
15091509

1510+
/*!
1511+
* \brief Index of read/write access within register
1512+
*/
1513+
typedef RegisterBase::index_type index_type;
1514+
1515+
/*!
1516+
* \brief Read value directly from the Register's backing store
1517+
* \note This is intentionally hiding the dmiRead() from the base
1518+
* class so we don't have to go through the dmiRead_() virtual method.
1519+
*/
1520+
template <typename T>
1521+
inline T dmiRead(index_type idx = 0) const
1522+
{
1523+
T res;
1524+
dmiReadImpl_(&res, sizeof(res), sizeof(res) * idx);
1525+
return res;
1526+
}
1527+
1528+
/*!
1529+
* \brief Write a value directly to this Register's backing store
1530+
* \note No masking, boundary checkor or notification is performed
1531+
* \note This is intentionally hiding the dmiWrite() from the base
1532+
* class so we don't have to go through the dmiWrite_() virtual method.
1533+
*/
1534+
template <typename T>
1535+
inline void dmiWrite(T val, index_type idx = 0)
1536+
{
1537+
dmiWriteImpl_(&val, sizeof(val), sizeof(val) * idx);
1538+
}
1539+
1540+
/*!
1541+
* \brief Write a value into this register without it being affected by the write-mask
1542+
* \warning This ignores read-only fields
1543+
* \note This is intentionally hiding the writeUnmasked() from the base
1544+
* class so we don't have to go through the dmiWriteImpl_() virtual method.
1545+
*/
1546+
template <typename T>
1547+
inline void writeUnmasked(T val, index_type idx = 0)
1548+
{
1549+
dmiWriteImpl_(&val, sizeof(T), idx);
1550+
}
1551+
15101552
private:
15111553
/*!
15121554
* \brief Discover and store the raw location of this Register's data
@@ -1536,7 +1578,7 @@ class Register : public RegisterBase
15361578

15371579
void dmiRead_(void *buf, size_t size, size_t offset = 0) const override final
15381580
{
1539-
memcpy(buf, raw_data_ptr_ + offset, size);
1581+
dmiReadImpl_(buf, size, offset);
15401582
}
15411583

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

15611603
void dmiWrite_(const void *buf, size_t size, size_t offset = 0) override final
1604+
{
1605+
dmiWriteImpl_(buf, size, offset);
1606+
}
1607+
1608+
inline void dmiReadImpl_(void *buf, size_t size, size_t offset = 0) const
1609+
{
1610+
memcpy(buf, raw_data_ptr_ + offset, size);
1611+
}
1612+
1613+
inline void dmiWriteImpl_(const void *buf, size_t size, size_t offset = 0)
15621614
{
15631615
memcpy(raw_data_ptr_ + offset, buf, size);
15641616
dview_.getLine()->flagDirty();

sparta/sparta/functional/RegisterSet.hpp

+11-8
Original file line numberDiff line numberDiff line change
@@ -480,8 +480,9 @@ class RegisterSet : public TreeNode
480480
const RegisterBase::Definition *defs,
481481
const RegisterProxyBase::Definition *proxy_defs,
482482
CurrentBankFunction cbfxn,
483-
RegisterTypeTag<RegisterT> tag)
484-
: TreeNode("regs",
483+
RegisterTypeTag<RegisterT> tag,
484+
const std::string& name = "regs")
485+
: TreeNode(name,
485486
TreeNode::GROUP_NAME_BUILTIN,
486487
TreeNode::GROUP_IDX_NONE,
487488
"Register set")
@@ -530,8 +531,9 @@ class RegisterSet : public TreeNode
530531
template <typename RegisterT>
531532
RegisterSet(TreeNode *parent,
532533
const RegisterBase::Definition *defs,
533-
RegisterTypeTag<RegisterT> tag)
534-
: RegisterSet(parent, defs, nullptr, nullptr, tag)
534+
RegisterTypeTag<RegisterT> tag,
535+
const std::string& name = "regs")
536+
: RegisterSet(parent, defs, nullptr, nullptr, tag, name)
535537
{
536538
// Handled in delegated consturctor
537539
}
@@ -541,18 +543,19 @@ class RegisterSet : public TreeNode
541543
create(TreeNode *parent,
542544
const RegisterBase::Definition *defs,
543545
const RegisterProxyBase::Definition *proxy_defs,
544-
CurrentBankFunction cbfxn)
546+
CurrentBankFunction cbfxn,
547+
const std::string& name = "regs")
545548
{
546549
return std::unique_ptr<RegisterSet>(new RegisterSet(
547-
parent, defs, proxy_defs, cbfxn, RegisterTypeTag<RegisterT>()));
550+
parent, defs, proxy_defs, cbfxn, RegisterTypeTag<RegisterT>(), name));
548551
}
549552

550553
template <typename RegisterT = Register>
551554
static std::unique_ptr<RegisterSet>
552-
create(TreeNode *parent, const RegisterBase::Definition *defs)
555+
create(TreeNode *parent, const RegisterBase::Definition *defs, const std::string& name = "regs")
553556
{
554557
return std::unique_ptr<RegisterSet>(new RegisterSet(
555-
parent, defs, RegisterTypeTag<RegisterT>()));
558+
parent, defs, RegisterTypeTag<RegisterT>(), name));
556559
}
557560

558561
/*!

sparta/sparta/kernel/DAG.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ namespace sparta
221221
VertexMap gops_;
222222
bool finalized_ = false;
223223
sparta::Scheduler* my_scheduler_ = nullptr;
224+
const log::MessageSource debug_logger_;
224225
};//End class DAG
225226

226227

sparta/sparta/parsers/ConfigEmitterYAML.hpp

+56-60
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "sparta/simulation/Parameter.hpp"
1515
#include "sparta/app/SimulationInfo.hpp"
1616
#include "sparta/simulation/TreeNodePrivateAttorney.hpp"
17+
#include "sparta/simulation/ParameterTree.hpp"
1718

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

@@ -80,6 +81,7 @@ class YAML : public ConfigEmitter
8081
* \post emitter_ will be nullptr
8182
*/
8283
void addParameters(TreeNode* device_tree,
84+
const ParameterTree* extensions_ptree,
8385
bool verbose=false)
8486
{
8587
sparta_assert(emitter_ == nullptr);
@@ -102,52 +104,26 @@ class YAML : public ConfigEmitter
102104

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

107-
if (!tree_node_extensions_.empty()) {
108-
for (auto & ext_info : tree_node_extensions_) {
109-
TreeNode * tn = ext_info.first;
110-
std::vector<std::pair<std::string, TreeNode::ExtensionsBase*>> & node_extensions =
111-
ext_info.second;
112-
113-
*emitter_ << YP::BeginMap;
114-
*emitter_ << YP::Key << tn->getLocation();
115-
*emitter_ << YP::Value;
116-
*emitter_ << YP::BeginMap;
117-
118-
for (auto & node_extension : node_extensions) {
119-
*emitter_ << YP::Key << ("extension." + node_extension.first);
120-
*emitter_ << YP::Value;
121-
*emitter_ << YP::BeginMap;
122-
123-
TreeNode::ExtensionsBase * ext_base = node_extension.second;
124-
ParameterSet * params = ext_base->getYamlOnlyParameters();
125-
auto param_names = params->getNames();
126-
for (const auto & param_name : param_names) {
127-
*emitter_ << YP::Key << param_name;
128-
*emitter_ << YP::Value // << YP::PadToColumn(50)
129-
<< params->getParameter(param_name)->getValueAsString();
130-
std::stringstream tags;
131-
params->getParameter(param_name)->stringizeTags(tags);
132-
*emitter_ << YP::Comment(tags.str());
133-
}
134-
135-
params = ext_base->getParameters();
136-
param_names = params->getNames();
137-
for (const auto & param_name : param_names) {
138-
*emitter_ << YP::Key << param_name;
139-
*emitter_ << YP::Value // << YP::PadToColumn(50)
140-
<< params->getParameter(param_name)->getValueAsString();
141-
std::stringstream tags;
142-
params->getParameter(param_name)->stringizeTags(tags);
143-
*emitter_ << YP::Comment(tags.str());
144-
}
145-
146-
*emitter_ << YP::EndMap;
147-
}
148-
*emitter_ << YP::EndMap;
149-
*emitter_ << YP::EndMap;
150-
}
108+
handleNode_(device_tree, verbose);
109+
110+
if (extensions_ptree) {
111+
// Note we use the ParameterTree to get the tree node extensions instead
112+
// of the device tree since using the device tree might serialize an extension
113+
// defn of:
114+
//
115+
// top.cpu.core*.extension.core_extensions:
116+
// name: value
117+
// name: value
118+
//
119+
// As:
120+
//
121+
// top.cpu.core0.extension.core_extensions:
122+
// name: value
123+
// name: value
124+
//
125+
// But the ParameterTree retains the wildcards in the path.
126+
handleNode_(extensions_ptree->getRoot());
151127
}
152128

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

173149

174150
private:
151+
/*!
152+
* \brief Recursively write the TreeNode extensions defns to YAML
153+
*/
154+
void handleNode_(const ParameterTree::Node* subtree)
155+
{
156+
sparta_assert(subtree);
157+
sparta_assert(emitter_ != nullptr);
158+
159+
if (subtree->getName() == "extension") {
160+
auto location_key = subtree->getParent()->getPath();
161+
*emitter_ << YP::BeginMap;
162+
*emitter_ << YP::Key << location_key;
163+
*emitter_ << YP::Value;
164+
*emitter_ << YP::BeginMap;
165+
166+
for (const auto child : subtree->getChildren()) {
167+
auto extension_name = child->getName();
168+
*emitter_ << YP::Key << ("extension." + extension_name);
169+
*emitter_ << YP::Value;
170+
*emitter_ << YP::BeginMap;
171+
for (const auto param : child->getChildren()) {
172+
*emitter_ << YP::Key << param->getName();
173+
*emitter_ << YP::Value << param->getValue();
174+
}
175+
*emitter_ << YP::EndMap;
176+
}
177+
178+
*emitter_ << YP::EndMap;
179+
*emitter_ << YP::EndMap;
180+
} else {
181+
for (const auto child : subtree->getChildren()) {
182+
handleNode_(child);
183+
}
184+
}
185+
}
175186

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

189-
const auto & extension_names = subtree->getAllExtensionNames();
190-
for (const auto & ext_name : extension_names) {
191-
auto extension = subtree->getExtension(ext_name);
192-
if (extension) {
193-
tree_node_extensions_[subtree].emplace_back(
194-
std::make_pair(ext_name, subtree->getExtension(ext_name)));
195-
}
196-
}
197-
198200
// Print parameter value if this node is a parameter
199201
const ParameterBase* pb = dynamic_cast<const ParameterBase*>(subtree);
200202
if(pb){
@@ -396,12 +398,6 @@ class YAML : public ConfigEmitter
396398
*/
397399
const bool show_param_descs_;
398400

399-
/*!
400-
* \brief Mapping from tree nodes to their named extensions, if any
401-
*/
402-
std::unordered_map<TreeNode*,
403-
std::vector<std::pair<std::string, TreeNode::ExtensionsBase*>>> tree_node_extensions_;
404-
405401
}; // class YAML
406402

407403
} // namespace ConfigEmitter

sparta/sparta/simulation/Unit.hpp

+5
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,11 @@ namespace sparta {
125125

126126
for(auto & event_node : unit_event_set_.getEvents(sparta::SchedulingPhase::Tick))
127127
{
128+
// This event does not participate in auto precedence.
129+
if(!event_node->doesParticipateInAutoPrecedence()) {
130+
continue;
131+
}
132+
128133
// Go through all of the registered InPorts and set these
129134
// ports to precede any events that are on the Tick phase.
130135
// This is for 0-cycle precedence only.

0 commit comments

Comments
 (0)