336 lines
8.6 KiB
C++
336 lines
8.6 KiB
C++
|
|
/*************************************************************************
|
|
*
|
|
* Copyright (c) 2023 Fabian Posch
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301, USA.
|
|
*
|
|
**************************************************************************
|
|
*/
|
|
|
|
#ifndef __PIPELINE_ARTIFACT_H__
|
|
#define __PIPELINE_ARTIFACT_H__
|
|
|
|
#include <act/act.h>
|
|
#include <vector>
|
|
#include <unordered_map>
|
|
#include <string>
|
|
#include <memory>
|
|
#include "util.h"
|
|
|
|
namespace pl {
|
|
|
|
/**
|
|
* @brief Representation of different artifact types
|
|
*/
|
|
enum class ArtifactType {UNKNOWN, ACT, SIM_CONFIG, SIGLIST, SIM_OUTPUT};
|
|
static std::unordered_map<std::string, ArtifactType> art_type_str = {
|
|
{"unknown", ArtifactType::UNKNOWN},
|
|
{"act", ArtifactType::ACT},
|
|
{"testcases", ArtifactType::SIM_CONFIG},
|
|
{"sig_list", ArtifactType::SIGLIST},
|
|
{"sim_output", ArtifactType::SIM_OUTPUT}
|
|
};
|
|
|
|
inline std::string to_string(ArtifactType const &value) {
|
|
std::string str = "unknown";
|
|
|
|
for (auto& it : art_type_str) {
|
|
if (it.second == value) {
|
|
str = it.first;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return str;
|
|
};
|
|
|
|
inline std::ostream& operator<<(std::ostream& os, ArtifactType const &rhs) {
|
|
os << to_string(rhs);
|
|
return os;
|
|
};
|
|
|
|
/** List of artifact names as well as types */
|
|
typedef std::vector<std::pair<std::string, ArtifactType>> artifact_list;
|
|
|
|
|
|
/**
|
|
* @brief An artifact is a data point which can be consumed or produced by a pipeline module
|
|
*/
|
|
class Artifact {
|
|
|
|
public:
|
|
|
|
/**
|
|
* @brief Construct a new blank Artifact
|
|
*
|
|
*/
|
|
Artifact();
|
|
|
|
/**
|
|
* @brief Get the type of the artifact the object is holding.
|
|
*
|
|
* Substitute for getting the object type
|
|
*
|
|
* @return ArtifactType
|
|
*/
|
|
virtual ArtifactType get_type() { return ArtifactType::UNKNOWN; };
|
|
|
|
|
|
/**
|
|
* @brief Get the content of the artifact
|
|
*
|
|
* @tparam T Content type the artifact is holding
|
|
* @return T Content of the artifact
|
|
*/
|
|
template<typename T>
|
|
T get_content();
|
|
|
|
|
|
/**
|
|
* @brief Get the number of elements in this artifact
|
|
*
|
|
* This is mostly relevant when uploading an artifact to the database cluster.
|
|
*
|
|
* @return long The number of elements in this artifact
|
|
*/
|
|
virtual long get_size() = 0;
|
|
|
|
|
|
/**
|
|
* @brief Inform a tool whether this artifact can be handled by multiple nodes
|
|
*
|
|
* By default, one artifact should only be handled once. However, there might be
|
|
* situations where multiple nodes can handle a single artifact. This could for example
|
|
* be a situation where a simulation for a design has a coverage model for constrained
|
|
* random testing. In this case we want to cover everything as fast as possible and
|
|
* simulation can be distributed.
|
|
*
|
|
* @return true The artifact can be handled by multiple nodes
|
|
* @return false The artifact cannot be handled by multiple nodes
|
|
*/
|
|
bool parallelizable() { return false; };
|
|
};
|
|
|
|
|
|
/**
|
|
* @brief ACT design artifact
|
|
*/
|
|
class ActArtifact: public Artifact {
|
|
public:
|
|
|
|
/**
|
|
* @brief Construct a new ACT design artifact
|
|
*
|
|
* @param design The design object the artifact should point to
|
|
*/
|
|
ActArtifact(std::shared_ptr<Act> design) { this->design = design; };
|
|
|
|
/**
|
|
* @brief Get the content of the artifact
|
|
*
|
|
* @return std::shared_ptr<Act> Pointer to the artifact's design file.
|
|
*/
|
|
std::shared_ptr<Act> get_content() { return design; };
|
|
|
|
|
|
/**
|
|
* @brief Returns the type of this artifact, which is ACT.
|
|
*
|
|
* @return ArtifactType Will return the ACT artifact type.
|
|
*/
|
|
ArtifactType get_type() override { return ArtifactType::ACT; };
|
|
|
|
|
|
/**
|
|
* @brief Get the number of elements in this artifact, which is 1 per definition
|
|
*
|
|
* @return long
|
|
*/
|
|
long get_size() { return 1; };
|
|
|
|
private:
|
|
|
|
std::shared_ptr<Act> design;
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
* @brief Struct to capture one testcase.
|
|
*/
|
|
struct testcase_t {
|
|
/** Commands to be executed for this testcase */
|
|
std::vector<std::string> commands;
|
|
/** Top process for the simulation */
|
|
std::string top;
|
|
/** This simulation should be run by multiple noes */
|
|
bool parallelizable;
|
|
/** Maximum pipeline load factor that should be allowed */
|
|
float max_plf;
|
|
};
|
|
|
|
/**
|
|
* @brief Artifact containing one or more configurations for actsim
|
|
*/
|
|
class SimConfigArtifact: public Artifact {
|
|
public:
|
|
|
|
SimConfigArtifact();
|
|
|
|
/**
|
|
* @brief Get the content of the artifact
|
|
*
|
|
* @return std::vector<testcase_t> Vector of all generated testcase structures
|
|
*/
|
|
std::vector<testcase_t>& get_content() { return testcases; };
|
|
|
|
|
|
/**
|
|
* @brief Add a testcase to the artifact
|
|
*
|
|
* @param testcase
|
|
*/
|
|
void add_testcase(testcase_t testcase);
|
|
|
|
|
|
/**
|
|
* @brief Returns the type of this artifact, which is SIM_CONFIG.
|
|
*
|
|
* @return ArtifactType Will return the SIM_CONFIG artifact type.
|
|
*/
|
|
ArtifactType get_type() override { return ArtifactType::SIM_CONFIG; };
|
|
|
|
|
|
/**
|
|
* @brief Get the number of testcases stored in this artifact
|
|
*
|
|
* @return long The size of the testcase vector
|
|
*/
|
|
long get_size() { return testcases.size(); };
|
|
|
|
/**
|
|
* @brief Can this simulation be handled by multiple nodes
|
|
*
|
|
* By default, one artifact should only be handled once. However, there might be
|
|
* situations where multiple nodes can handle a single artifact. This could for example
|
|
* be a situation where a simulation for a design has a coverage model for constrained
|
|
* random testing. In this case we want to cover everything as fast as possible and
|
|
* simulation can be distributed.
|
|
*
|
|
* @return true The simulation can be handled by multiple nodes
|
|
* @return false The simulation cannot be handled by multiple nodes
|
|
*/
|
|
bool parallelizable() {
|
|
if (this->testcases.size() != 1) return false;
|
|
return this->testcases.front().parallelizable;
|
|
};
|
|
|
|
private:
|
|
|
|
std::vector<testcase_t> testcases;
|
|
};
|
|
|
|
/** Reference to a signal in an ACT design */
|
|
typedef std::string signal_t;
|
|
|
|
/**
|
|
* @brief Artifact containing a list of signals
|
|
*/
|
|
class SignalListArtifact: public Artifact {
|
|
public:
|
|
|
|
/**
|
|
* @brief Get the content of the artifact
|
|
*
|
|
* @return std::vector<signal_t> Vector of all captured signals structures
|
|
*/
|
|
std::vector<signal_t> get_content() { return signals; };
|
|
|
|
|
|
/**
|
|
* @brief Add a signal to the artifact
|
|
*
|
|
* @param testcase
|
|
*/
|
|
void add_signal(signal_t signal);
|
|
|
|
|
|
/**
|
|
* @brief Returns the type of this artifact, which is SIGLIST.
|
|
*
|
|
* @return ArtifactType Will return the SIGLIST artifact type.
|
|
*/
|
|
ArtifactType get_type() override { return ArtifactType::SIGLIST; };
|
|
|
|
|
|
/**
|
|
* @brief Get the number of signals stored in this artifact
|
|
*
|
|
* @return long The size of the signals vector
|
|
*/
|
|
long get_size() { return signals.size(); };
|
|
|
|
private:
|
|
|
|
std::vector<signal_t> signals;
|
|
};
|
|
|
|
/**
|
|
* @brief Artifact containing simulator output from actsim
|
|
*/
|
|
class SimOutputArtifact: public Artifact {
|
|
public:
|
|
|
|
/**
|
|
* @brief Get the content of the artifact
|
|
*
|
|
* @return std::vector<testcase_t> Vector of all generated simulator output lines
|
|
*/
|
|
std::vector<std::string>& get_content() { return sim_log; };
|
|
|
|
|
|
/**
|
|
* @brief Add a log line to the artifact
|
|
*
|
|
* @param log_line
|
|
*/
|
|
void add_log_output(std::string log_line);
|
|
|
|
|
|
/**
|
|
* @brief Returns the type of this artifact, which is SIM_OUTPUT.
|
|
*
|
|
* @return ArtifactType Will return the SIM_OUTPUT artifact type.
|
|
*/
|
|
ArtifactType get_type() override { return ArtifactType::SIM_OUTPUT; };
|
|
|
|
|
|
/**
|
|
* @brief Get the number of log lines stored in this artifact
|
|
*
|
|
* @return long The size of the log lines vector
|
|
*/
|
|
long get_size() { return sim_log.size(); };
|
|
|
|
private:
|
|
|
|
std::vector<std::string> sim_log;
|
|
};
|
|
|
|
};
|
|
|
|
#endif
|