Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Uniform distribution support for crave vairables #10

Merged
merged 15 commits into from
Apr 5, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions crave/src/crave/backend/Generator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
****************************************************************************************/


#pragma once

#include <string>
Expand All @@ -37,7 +35,7 @@ namespace crave {

/*!
* \brief Backend generator to generate random values with constraints.
*
*
* Try to avoid usage of this class directly.
* CRAVE usually uses this class internally.
*/
Expand Down Expand Up @@ -145,6 +143,7 @@ struct Generator {

void addVecId(int id) { to_be_generated_vec_ids_.insert(id); }

VariableContainer* getVarCtn ();
private:
// constraints
ConstraintManager constr_mng_;
Expand Down
20 changes: 11 additions & 9 deletions crave/src/crave/experimental/Object.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,26 @@
// SOFTWARE.
****************************************************************************************/


#pragma once

#include <iostream>
#include <list>
#include <string>
#include <unordered_map>


namespace crave {

struct Generator;

struct crv_object_name;
class crv_object;
struct VariableContainer;

/**
* \ingroup newAPI
* \brief Class for names of CRAVE objects.
*
*
* This class is a type safe class to wrap the name of an object in CRAVE.
*/
struct crv_object_name {
Expand Down Expand Up @@ -96,21 +97,21 @@ class crv_object {

/**
* \brief Return the type of the object as a string.
*
*
* The type is most likely the name of the class the object is made from.
*
*
* \return Type of the object as a string.
*/
virtual std::string obj_kind() const { return "crv_object"; }

/**
* \brief Randomizes the variables in this object.
*
*
* The variables must be of type crv_variable in order to be randomized.
* While randomizing, all constraints that are part of the object will be used to get a solution.
* These constraints may produce contradicts and cannot be solved.
* In that case, this method returns false.
*
*
* \return true if a solution is found, false otherwise.
*/
virtual bool randomize() { return false; }
Expand All @@ -136,7 +137,6 @@ class crv_object {
* get the root object of the hierarchy
*/
static crv_object* root();

/**
* find the object with a given name
*/
Expand All @@ -147,7 +147,7 @@ class crv_object {
*/
static unsigned count();

protected:
public:
/**
* copy constructor
*/
Expand All @@ -162,6 +162,8 @@ class crv_object {

virtual void recursive_build(Generator& gen) const;

virtual VariableContainer* check_default_constraints(Generator& gen);

std::string name_; /** < name of the object*/
std::string orig_name_; /** < original name of the object*/
crv_object* parent_; /** < parent node*/
Expand Down
3 changes: 2 additions & 1 deletion crave/src/crave/experimental/SequenceItem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
// SOFTWARE.
****************************************************************************************/


#pragma once

#include "Coverage.hpp"
Expand Down Expand Up @@ -84,6 +83,8 @@ class crv_sequence_item : public crv_object {
*/
void goal(crv_covergroup& group);

void crosscheck_constraints ();

protected:
void request_rebuild() override;

Expand Down
46 changes: 44 additions & 2 deletions crave/src/crave/experimental/SystemC.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
// SOFTWARE.
****************************************************************************************/


#pragma once

#include "Variable.hpp"
Expand All @@ -45,12 +44,14 @@ struct to_constant_expr<T, typename std::enable_if<is_sysc_dt<T>::value>::type>
* crv_variable for SystemC data types
*/
template <typename T>
class crv_variable<T, typename std::enable_if<is_sysc_dt<T>::value>::type> : public crv_variable_base<T> {
class crv_variable<T, typename std::enable_if<is_sysc_dt<T>::value>::type> : public crv_var, public crv_variable_base<T> {
CRV_VARIABLE_COMMON_CONSTRUCTORS(T);
CRV_VARIABLE_ASSIGNMENT_INTERFACE(T);
CRV_VARIABLE_ARITHMETIC_INTERFACE(T);
CRV_VARIABLE_BITWISE_INTERFACE(T);

crv_constraint c_var_uniform;

public:
/**
* randomize variable
Expand All @@ -61,6 +62,47 @@ class crv_variable<T, typename std::enable_if<is_sysc_dt<T>::value>::type> : pub
this->value = dist.nextValue();
return true;
}

void create_default_cstr () {
create_distribution (T());
}

template <typename L>
void create_distribution (const L &tvar, typename std::enable_if<is_signed<L>::value, void>::type* = nullptr) {
c_var_uniform = {dist(this->var, make_distribution(weighted_range<int64_t>(get_sc_dt_min_numeric_limit(tvar), get_sc_dt_max_numeric_limit(tvar),1)))};
}

template <typename L>
void create_distribution (const L &tvar, typename std::enable_if<is_unsigned<L>::value, void>::type* = nullptr) {
c_var_uniform = {dist(this->var, make_distribution(weighted_range<uint64_t>(get_sc_dt_min_numeric_limit(tvar), get_sc_dt_max_numeric_limit(tvar),1)))};
}


template <typename L >
int64_t get_sc_dt_min_numeric_limit (const L &var, typename std::enable_if<is_signed<L>::value, void>::type* = nullptr) {
return (int64_t)(-(pow(2,var.length()-1)));
}

template <typename L>
int64_t get_sc_dt_max_numeric_limit (const L &var, typename std::enable_if<is_signed<L>::value, void>::type* = nullptr) {
return (int64_t)(pow(2,var.length()-1) - 1);
}

template <typename L >
uint64_t get_sc_dt_min_numeric_limit(const L &var, typename std::enable_if<is_unsigned<L>::value, void>::type* = nullptr) {
return (uint64_t)(0);
}

template <typename L >
uint64_t get_sc_dt_max_numeric_limit (const L &var, typename std::enable_if<is_unsigned<L>::value, void>::type* = nullptr) {
return (uint64_t)(pow(2,var.length()) - 1);
}

unsigned getVarID() {
return crv_variable_base<T>::id();
}


};

} // namespace crave
88 changes: 81 additions & 7 deletions crave/src/crave/experimental/Variable.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/****************************************************************************************
//****************************************************************************************
// MIT License
//***************************************************************************************
//****************************************************************************************
// Copyright (c) 2012-2020 University of Bremen, Germany.
// Copyright (c) 2015-2020 DFKI GmbH Bremen, Germany.
// Copyright (c) 2020 Johannes Kepler University Linz, Austria.
Expand All @@ -22,15 +22,18 @@
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
****************************************************************************************/

//****************************************************************************************

#pragma once

#include "VariableBase.hpp"
#include "../frontend/Operators.hpp"
#include "../frontend/WeightedRange.hpp"

#include "../frontend/Distribution.hpp"
#include "../ir/UserExpression.hpp"
#include "Constraint.hpp"


namespace crave {

Expand Down Expand Up @@ -68,7 +71,7 @@ distribution_tag<T> make_distribution(weighted_range<T> const& range, Args... ar
*/
#define CRV_VARIABLE_COMMON_CONSTRUCTORS(Typename) \
public: \
crv_variable(crv_object_name name = "var") {} \
crv_variable(crv_object_name name = "var") {create_default_cstr ();} \
crv_variable(const crv_variable& other) : crv_variable_base<Typename>(other) {}

/**
Expand Down Expand Up @@ -158,6 +161,26 @@ distribution_tag<T> make_distribution(weighted_range<T> const& range, Args... ar
return *this; \
}

/**
* boolean operators
* @param i value for bitwise operation
*/
#define CRV_VARIABLE_BOOLEAN_INTERFACE(Typename) \
public: \
crv_variable<Typename>& operator&=(Typename i) { \
this->value &= i; \
return *this; \
} \
crv_variable<Typename>& operator|=(Typename i) { \
this->value |= i; \
return *this; \
} \
crv_variable<Typename>& operator^=(Typename i) { \
this->value ^= i; \
return *this; \
} \


/*!
*\ingroup newAPI
*\brief A randomizable variable of type T in new API.
Expand Down Expand Up @@ -189,20 +212,31 @@ distribution_tag<T> make_distribution(weighted_range<T> const& range, Args... ar
* If two variables are bound together, they share the same value.
* </p>
*/


class crv_var {
public:
virtual ~crv_var() {}
virtual unsigned getVarID() = 0;
};

template <typename T, typename Enable = void>
class crv_variable {};

/**
* class for randomisation of a variable
*/
template <typename T>
class crv_variable<T, typename std::enable_if<std::is_integral<T>::value>::type> : public crv_variable_base<T> {
template <typename T >
class crv_variable<T, typename std::enable_if<std::is_integral<T>::value>::type> : public crv_var, public crv_variable_base<T> {
CRV_VARIABLE_COMMON_CONSTRUCTORS(T);
CRV_VARIABLE_ASSIGNMENT_INTERFACE(T);
CRV_VARIABLE_ARITHMETIC_INTERFACE(T);
CRV_VARIABLE_BITWISE_INTERFACE(T);

crv_constraint c_var_uniform;

public:

/**
* generate random value
*/
Expand All @@ -211,8 +245,48 @@ class crv_variable<T, typename std::enable_if<std::is_integral<T>::value>::type>
this->value = dist.nextValue();
return true;
}

void create_default_cstr () {
c_var_uniform = { dist(this->var, make_distribution(range<T>(std::numeric_limits<T>::min(), std::numeric_limits<T>::max())))};
}

unsigned getVarID() {
return crv_variable_base<T>::id();
}
};


/**
* class for randomisation of a variable
*/
template <>
class crv_variable<bool> : public crv_var, public crv_variable_base<bool> {
CRV_VARIABLE_COMMON_CONSTRUCTORS(bool);
CRV_VARIABLE_ASSIGNMENT_INTERFACE(bool);
//CRV_VARIABLE_ARITHMETIC_INTERFACE(bool);
CRV_VARIABLE_BOOLEAN_INTERFACE(bool);

crv_constraint c_var_uniform;
public:
/**
* generate random value
*/
bool randomize() override {
static distribution<bool> dist;
this->value = dist.nextValue();
return true;
}

void create_default_cstr () {
c_var_uniform = { dist(this->var, distribution<bool>::create(0.5))};
}

unsigned getVarID() {
return crv_variable_base<bool>::id();
}
};


template <typename T>
struct bitsize_traits<crv_variable<T>> : public bitsize_traits<T> {};

Expand Down
4 changes: 3 additions & 1 deletion crave/src/crave/frontend/bitsize_traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@
// SOFTWARE.
****************************************************************************************/


#pragma once

#include <boost/mpl/int.hpp>
#include <boost/mpl/sizeof.hpp>
#include <boost/mpl/times.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_signed.hpp>
#include <boost/type_traits/is_unsigned.hpp>
#include <boost/utility/enable_if.hpp>

namespace crave {
Expand Down Expand Up @@ -112,6 +112,8 @@ struct is_crave_variable<write_ref_tag<T> > : boost::mpl::true_ {};
template <typename T>
struct is_signed : public boost::is_signed<T> {};

template <typename T>
struct is_unsigned : public boost::is_unsigned<T> {};
/**
* assume bool to be signed (i.e. will be converted to signed bv)
*/
Expand Down
10 changes: 9 additions & 1 deletion crave/src/crave/frontend/bitsize_traits_sysc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
// SOFTWARE.
****************************************************************************************/


#pragma once

#include <sysc/datatypes/bit/sc_bv.h>
Expand All @@ -48,6 +47,15 @@ struct is_signed<sc_dt::sc_int<N> > : boost::mpl::true_ {};
template <int N>
struct is_signed<sc_dt::sc_uint<N> > : boost::mpl::false_ {};

template <int N>
struct is_unsigned<sc_dt::sc_bv<N> > : boost::mpl::true_ {};

template <int N>
struct is_unsigned<sc_dt::sc_int<N> > : boost::mpl::false_ {};

template <int N>
struct is_unsigned<sc_dt::sc_uint<N> > : boost::mpl::true_ {};

template <typename T, int N = 0>
struct is_sysc_dt : boost::mpl::false_ {};

Expand Down
Loading