require CUDD
Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
parent
2da2064852
commit
e3a1fd792c
|
|
@ -28,7 +28,6 @@ project(STA VERSION 2.6.0
|
|||
LANGUAGES CXX
|
||||
)
|
||||
|
||||
option(USE_CUDD "Use CUDD BDD package" ON)
|
||||
option(CUDD_DIR "CUDD BDD package directory")
|
||||
option(USE_TCL_READLINE "Use TCL readliine package" ON)
|
||||
option(USE_SANITIZE "Compile with santize address enabled")
|
||||
|
|
@ -371,30 +370,25 @@ find_package(Eigen3 REQUIRED)
|
|||
#
|
||||
# Locate CUDD bdd package.
|
||||
#
|
||||
set(CUDD 0)
|
||||
if (USE_CUDD)
|
||||
find_library(CUDD_LIB
|
||||
NAME cudd
|
||||
PATHS ${CUDD_DIR}
|
||||
PATH_SUFFIXES lib lib/cudd cudd/.libs
|
||||
)
|
||||
if (CUDD_LIB)
|
||||
message(STATUS "CUDD library: ${CUDD_LIB}")
|
||||
get_filename_component(CUDD_LIB_DIR "${CUDD_LIB}" PATH)
|
||||
get_filename_component(CUDD_LIB_PARENT1 "${CUDD_LIB_DIR}" PATH)
|
||||
find_file(CUDD_HEADER cudd.h
|
||||
PATHS ${CUDD_LIB_PARENT1} ${CUDD_LIB_PARENT1}/include ${CUDD_LIB_PARENT1}/include/cudd)
|
||||
if (CUDD_HEADER)
|
||||
get_filename_component(CUDD_INCLUDE "${CUDD_HEADER}" PATH)
|
||||
message(STATUS "CUDD header: ${CUDD_HEADER}")
|
||||
# Referenced by StaConfig.hh.cmake
|
||||
set(CUDD 1)
|
||||
else()
|
||||
message(STATUS "CUDD header: not found")
|
||||
endif()
|
||||
find_library(CUDD_LIB
|
||||
NAME cudd
|
||||
PATHS ${CUDD_DIR}
|
||||
PATH_SUFFIXES lib lib/cudd cudd/.libs
|
||||
)
|
||||
if (CUDD_LIB)
|
||||
message(STATUS "CUDD library: ${CUDD_LIB}")
|
||||
get_filename_component(CUDD_LIB_DIR "${CUDD_LIB}" PATH)
|
||||
get_filename_component(CUDD_LIB_PARENT1 "${CUDD_LIB_DIR}" PATH)
|
||||
find_file(CUDD_HEADER cudd.h
|
||||
PATHS ${CUDD_LIB_PARENT1} ${CUDD_LIB_PARENT1}/include ${CUDD_LIB_PARENT1}/include/cudd)
|
||||
if (CUDD_HEADER)
|
||||
get_filename_component(CUDD_INCLUDE "${CUDD_HEADER}" PATH)
|
||||
message(STATUS "CUDD header: ${CUDD_HEADER}")
|
||||
else()
|
||||
message(STATUS "CUDD library: not found")
|
||||
message(STATUS "CUDD header: not found")
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "CUDD library: not found")
|
||||
endif()
|
||||
|
||||
if("${SSTA}" STREQUAL "")
|
||||
|
|
@ -517,6 +511,7 @@ target_link_libraries(OpenSTA
|
|||
Eigen3::Eigen
|
||||
${TCL_LIBRARY}
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
${CUDD_LIB}
|
||||
)
|
||||
|
||||
if (TCL_READLINE_LIBRARY)
|
||||
|
|
@ -527,9 +522,7 @@ if (ZLIB_LIBRARIES)
|
|||
target_link_libraries(OpenSTA ${ZLIB_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if (CUDD_LIB)
|
||||
target_link_libraries(OpenSTA ${CUDD_LIB})
|
||||
endif()
|
||||
target_link_libraries(OpenSTA )
|
||||
|
||||
target_include_directories(OpenSTA
|
||||
PUBLIC
|
||||
|
|
|
|||
|
|
@ -103,9 +103,9 @@ External library dependencies:
|
|||
```
|
||||
Ubuntu Macos license
|
||||
eigen 3.4.0 3.4.0 MPL2 required
|
||||
cudd 3.0.0 3.0.0 BSD required
|
||||
tclreadline 2.3.8 2.3.8 BSD optional
|
||||
zLib 1.2.5 1.2.8 zlib optional
|
||||
cudd 3.0.0 3.0.0 BSD optional
|
||||
```
|
||||
|
||||
The [TCL readline library](https://tclreadline.sourceforge.net/tclreadline.html)
|
||||
|
|
|
|||
|
|
@ -7,8 +7,9 @@ Release 2.6.0 2024/07/??
|
|||
-------------------------
|
||||
|
||||
The version of c++ used by OpenSTA is now 17.
|
||||
The Cudd BBD packager is now required.
|
||||
|
||||
The USE_CUDD and USE_TCL_READLINE options default to ON.
|
||||
The USE_TCL_READLINE option defaults to ON.
|
||||
|
||||
Release 2.5.0 2024/01/17
|
||||
-------------------------
|
||||
|
|
|
|||
|
|
@ -18,16 +18,10 @@
|
|||
|
||||
#include <map>
|
||||
|
||||
#include "cudd.h"
|
||||
#include "StaState.hh"
|
||||
#include "LibertyClass.hh"
|
||||
|
||||
#if CUDD
|
||||
#include "cudd.h"
|
||||
#else
|
||||
struct DdNode;
|
||||
struct DdManager;
|
||||
#endif
|
||||
|
||||
namespace sta {
|
||||
|
||||
typedef std::map<const LibertyPort*, DdNode*> BddPortVarMap;
|
||||
|
|
|
|||
108
power/Power.cc
108
power/Power.cc
|
|
@ -502,8 +502,6 @@ Power::clockGatePins(const Instance *inst,
|
|||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
#if CUDD
|
||||
|
||||
PwrActivity
|
||||
Power::evalActivity(FuncExpr *expr,
|
||||
const Instance *inst)
|
||||
|
|
@ -609,112 +607,6 @@ Power::evalBddActivity(DdNode *bdd,
|
|||
return activity;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
PwrActivity
|
||||
Power::evalActivity(FuncExpr *expr,
|
||||
const Instance *inst)
|
||||
{
|
||||
return evalActivity(expr, inst, nullptr, true);
|
||||
}
|
||||
|
||||
// Eval activity thru expr.
|
||||
// With cofactor_port eval the positive/negative cofactor of expr wrt cofactor_port.
|
||||
PwrActivity
|
||||
Power::evalActivity(FuncExpr *expr,
|
||||
const Instance *inst,
|
||||
const LibertyPort *cofactor_port,
|
||||
bool cofactor_positive)
|
||||
{
|
||||
switch (expr->op()) {
|
||||
case FuncExpr::op_port: {
|
||||
LibertyPort *port = expr->port();
|
||||
if (port == cofactor_port) {
|
||||
if (cofactor_positive)
|
||||
return PwrActivity(0.0, 1.0, PwrActivityOrigin::constant);
|
||||
else
|
||||
return PwrActivity(0.0, 0.0, PwrActivityOrigin::constant);
|
||||
}
|
||||
if (port->direction()->isInternal())
|
||||
return findSeqActivity(inst, port);
|
||||
else {
|
||||
Pin *pin = findLinkPin(inst, port);
|
||||
if (pin) {
|
||||
PwrActivity activity = findActivity(pin);
|
||||
activity.setOrigin(PwrActivityOrigin::propagated);
|
||||
return activity;
|
||||
}
|
||||
}
|
||||
return PwrActivity(0.0, 0.0, PwrActivityOrigin::constant);
|
||||
}
|
||||
case FuncExpr::op_not: {
|
||||
PwrActivity activity1 = evalActivity(expr->left(), inst,
|
||||
cofactor_port, cofactor_positive);
|
||||
return PwrActivity(activity1.activity(),
|
||||
1.0 - activity1.duty(),
|
||||
PwrActivityOrigin::propagated);
|
||||
}
|
||||
case FuncExpr::op_or: {
|
||||
PwrActivity activity1 = evalActivity(expr->left(), inst,
|
||||
cofactor_port, cofactor_positive);
|
||||
PwrActivity activity2 = evalActivity(expr->right(), inst,
|
||||
cofactor_port, cofactor_positive);
|
||||
float p1 = 1.0 - activity1.duty();
|
||||
float p2 = 1.0 - activity2.duty();
|
||||
return PwrActivity(activity1.activity() * p2 + activity2.activity() * p1,
|
||||
// d1 + d2 - d1 * d2
|
||||
1.0 - p1 * p2,
|
||||
PwrActivityOrigin::propagated);
|
||||
}
|
||||
case FuncExpr::op_and: {
|
||||
PwrActivity activity1 = evalActivity(expr->left(), inst,
|
||||
cofactor_port, cofactor_positive);
|
||||
PwrActivity activity2 = evalActivity(expr->right(), inst,
|
||||
cofactor_port, cofactor_positive);
|
||||
float p1 = activity1.duty();
|
||||
float p2 = activity2.duty();
|
||||
return PwrActivity(activity1.activity() * p2 + activity2.activity() * p1,
|
||||
p1 * p2,
|
||||
PwrActivityOrigin::propagated);
|
||||
}
|
||||
case FuncExpr::op_xor: {
|
||||
PwrActivity activity1 = evalActivity(expr->left(), inst,
|
||||
cofactor_port, cofactor_positive);
|
||||
PwrActivity activity2 = evalActivity(expr->right(), inst,
|
||||
cofactor_port, cofactor_positive);
|
||||
float d1 = activity1.duty();
|
||||
float d2 = activity2.duty();
|
||||
float p1 = d1 * (1.0 - d2);
|
||||
float p2 = (1.0 - d1) * d2;
|
||||
return PwrActivity(activity1.activity() + activity2.activity(),
|
||||
p1 + p2,
|
||||
PwrActivityOrigin::propagated);
|
||||
}
|
||||
case FuncExpr::op_one:
|
||||
return PwrActivity(0.0, 1.0, PwrActivityOrigin::constant);
|
||||
case FuncExpr::op_zero:
|
||||
return PwrActivity(0.0, 0.0, PwrActivityOrigin::constant);
|
||||
}
|
||||
return PwrActivity();
|
||||
}
|
||||
|
||||
// Eval activity of difference(expr) wrt cofactor port.
|
||||
float
|
||||
Power::evalDiffDuty(FuncExpr *expr,
|
||||
LibertyPort *cofactor_port,
|
||||
const Instance *inst)
|
||||
{
|
||||
// Activity of positive/negative cofactors.
|
||||
PwrActivity pos = evalActivity(expr, inst, cofactor_port, true);
|
||||
PwrActivity neg = evalActivity(expr, inst, cofactor_port, false);
|
||||
// difference = xor(pos, neg).
|
||||
float p1 = pos.duty() * (1.0 - neg.duty());
|
||||
float p2 = neg.duty() * (1.0 - pos.duty());
|
||||
return p1 + p2;
|
||||
}
|
||||
|
||||
#endif // CUDD
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -16,30 +16,11 @@
|
|||
|
||||
#include "Bdd.hh"
|
||||
|
||||
#include "cudd.h"
|
||||
#include "StaConfig.hh"
|
||||
#include "Report.hh"
|
||||
#include "FuncExpr.hh"
|
||||
|
||||
#if CUDD
|
||||
#include "cudd.h"
|
||||
#else
|
||||
#include <cstdint>
|
||||
#define CUDD_UNIQUE_SLOTS 0
|
||||
#define CUDD_CACHE_SLOTS 0
|
||||
DdManager *Cudd_Init(int, int, int, int, int) { return nullptr; }
|
||||
void Cudd_Quit(void *) {}
|
||||
DdNode *Cudd_Not(void *) { return nullptr; }
|
||||
DdNode *Cudd_bddOr(void *, void *, void *) { return nullptr; }
|
||||
DdNode *Cudd_bddAnd(void *, void *, void *) { return nullptr; }
|
||||
DdNode *Cudd_bddXor(void *, void *, void *) { return nullptr; }
|
||||
DdNode *Cudd_ReadOne(void *) { return nullptr; }
|
||||
DdNode *Cudd_ReadLogicZero(void *) { return nullptr; }
|
||||
DdNode *Cudd_bddNewVar(void *) { return nullptr; }
|
||||
int Cudd_NodeReadIndex(void *) { return 0;}
|
||||
void Cudd_Ref(void *) {}
|
||||
void Cudd_RecursiveDeref(void *, void *) {}
|
||||
#endif
|
||||
|
||||
namespace sta {
|
||||
|
||||
Bdd::Bdd(const StaState *sta) :
|
||||
|
|
|
|||
287
search/Sim.cc
287
search/Sim.cc
|
|
@ -16,7 +16,9 @@
|
|||
|
||||
#include "Sim.hh"
|
||||
|
||||
#include "StaConfig.hh" // CUDD
|
||||
// https://davidkebo.com/cudd
|
||||
#include "cudd.h"
|
||||
|
||||
#include "Error.hh"
|
||||
#include "Mutex.hh"
|
||||
#include "Debug.hh"
|
||||
|
|
@ -32,14 +34,6 @@
|
|||
#include "Sdc.hh"
|
||||
#include "Graph.hh"
|
||||
|
||||
#if CUDD
|
||||
// https://davidkebo.com/cudd
|
||||
#include "cudd.h"
|
||||
#else
|
||||
#define Cudd_Init(ignore1, ignore2, ignore3, ignore4, ignore5) nullptr
|
||||
#define Cudd_Quit(ignore1)
|
||||
#endif
|
||||
|
||||
namespace sta {
|
||||
|
||||
static LogicValue
|
||||
|
|
@ -69,8 +63,6 @@ Sim::~Sim()
|
|||
delete observer_;
|
||||
}
|
||||
|
||||
#if CUDD
|
||||
|
||||
TimingSense
|
||||
Sim::functionSense(const FuncExpr *expr,
|
||||
const Pin *input_pin,
|
||||
|
|
@ -159,279 +151,6 @@ Sim::funcBddSim(const FuncExpr *expr,
|
|||
return bdd;
|
||||
}
|
||||
|
||||
#else
|
||||
// No CUDD.
|
||||
|
||||
static LogicValue
|
||||
logicOr(LogicValue value1,
|
||||
LogicValue value2)
|
||||
{
|
||||
static LogicValue logic_or[5][5] =
|
||||
{{LogicValue::zero, LogicValue::one, LogicValue::unknown, LogicValue::unknown, LogicValue::unknown},
|
||||
{LogicValue::one, LogicValue::one, LogicValue::one, LogicValue::one, LogicValue::one},
|
||||
{LogicValue::unknown,LogicValue::one, LogicValue::unknown, LogicValue::unknown, LogicValue::unknown},
|
||||
{LogicValue::unknown,LogicValue::one, LogicValue::unknown, LogicValue::unknown, LogicValue::unknown},
|
||||
{LogicValue::unknown,LogicValue::one, LogicValue::unknown, LogicValue::unknown, LogicValue::unknown}};
|
||||
return logic_or[int(value1)][int(value2)];
|
||||
}
|
||||
|
||||
static LogicValue
|
||||
logicAnd(LogicValue value1,
|
||||
LogicValue value2)
|
||||
{
|
||||
static LogicValue logic_and[5][5] =
|
||||
{{LogicValue::zero,LogicValue::zero, LogicValue::zero, LogicValue::zero, LogicValue::zero},
|
||||
{LogicValue::zero,LogicValue::one, LogicValue::unknown,LogicValue::unknown, LogicValue::unknown},
|
||||
{LogicValue::zero,LogicValue::unknown,LogicValue::unknown,LogicValue::unknown, LogicValue::unknown},
|
||||
{LogicValue::zero,LogicValue::unknown,LogicValue::unknown,LogicValue::unknown, LogicValue::unknown},
|
||||
{LogicValue::zero,LogicValue::unknown,LogicValue::unknown,LogicValue::unknown, LogicValue::unknown}};
|
||||
return logic_and[int(value1)][int(value2)];
|
||||
}
|
||||
|
||||
static LogicValue
|
||||
logicXor(LogicValue value1,
|
||||
LogicValue value2)
|
||||
{
|
||||
static LogicValue logic_xor[5][5]=
|
||||
{{LogicValue::zero, LogicValue::one, LogicValue::unknown,LogicValue::unknown, LogicValue::unknown},
|
||||
{LogicValue::one, LogicValue::zero, LogicValue::unknown,LogicValue::unknown, LogicValue::unknown},
|
||||
{LogicValue::unknown,LogicValue::unknown,LogicValue::unknown,LogicValue::unknown, LogicValue::unknown},
|
||||
{LogicValue::unknown,LogicValue::unknown,LogicValue::unknown,LogicValue::unknown, LogicValue::unknown},
|
||||
{LogicValue::unknown,LogicValue::unknown,LogicValue::unknown,LogicValue::unknown, LogicValue::unknown}};
|
||||
return logic_xor[int(value1)][int(value2)];
|
||||
}
|
||||
|
||||
static TimingSense
|
||||
senseNot(TimingSense sense)
|
||||
{
|
||||
static TimingSense sense_not[5] = {TimingSense::negative_unate,
|
||||
TimingSense::positive_unate,
|
||||
TimingSense::non_unate,
|
||||
TimingSense::none,
|
||||
TimingSense::unknown};
|
||||
return sense_not[int(sense)];
|
||||
}
|
||||
|
||||
static TimingSense
|
||||
senseAndOr(TimingSense sense1,
|
||||
TimingSense sense2)
|
||||
{
|
||||
static TimingSense sense_and_or[5][5] =
|
||||
{{TimingSense::positive_unate, TimingSense::non_unate,
|
||||
TimingSense::non_unate, TimingSense::positive_unate, TimingSense::unknown},
|
||||
{TimingSense::non_unate, TimingSense::negative_unate,
|
||||
TimingSense::non_unate, TimingSense::negative_unate, TimingSense::unknown},
|
||||
{TimingSense::non_unate, TimingSense::non_unate, TimingSense::non_unate,
|
||||
TimingSense::non_unate, TimingSense::unknown},
|
||||
{TimingSense::positive_unate, TimingSense::negative_unate,
|
||||
TimingSense::non_unate, TimingSense::none, TimingSense::unknown},
|
||||
{TimingSense::unknown, TimingSense::unknown,
|
||||
TimingSense::unknown, TimingSense::non_unate, TimingSense::unknown}};
|
||||
return sense_and_or[int(sense1)][int(sense2)];
|
||||
}
|
||||
|
||||
static TimingSense
|
||||
senseXor(TimingSense sense1,
|
||||
TimingSense sense2)
|
||||
{
|
||||
static TimingSense xor_sense[5][5] =
|
||||
{{TimingSense::non_unate, TimingSense::non_unate,
|
||||
TimingSense::non_unate, TimingSense::non_unate, TimingSense::unknown},
|
||||
{TimingSense::non_unate, TimingSense::non_unate,
|
||||
TimingSense::non_unate, TimingSense::non_unate, TimingSense::unknown},
|
||||
{TimingSense::non_unate, TimingSense::non_unate,
|
||||
TimingSense::non_unate, TimingSense::non_unate, TimingSense::unknown},
|
||||
{TimingSense::non_unate, TimingSense::non_unate,
|
||||
TimingSense::non_unate, TimingSense::none, TimingSense::unknown},
|
||||
{TimingSense::unknown, TimingSense::unknown,
|
||||
TimingSense::unknown, TimingSense::unknown, TimingSense::unknown}};
|
||||
return xor_sense[int(sense1)][int(sense2)];
|
||||
}
|
||||
|
||||
TimingSense
|
||||
Sim::functionSense(const FuncExpr *expr,
|
||||
const Pin *input_pin,
|
||||
const Instance *inst)
|
||||
{
|
||||
TimingSense sense = TimingSense::none;
|
||||
LogicValue value = LogicValue::unknown;
|
||||
functionSense(expr, input_pin, inst, sense, value);
|
||||
return sense;
|
||||
}
|
||||
|
||||
void
|
||||
Sim::functionSense(const FuncExpr *expr,
|
||||
const Pin *input_pin,
|
||||
const Instance *inst,
|
||||
// return values
|
||||
TimingSense &sense,
|
||||
LogicValue &value) const
|
||||
{
|
||||
switch (expr->op()) {
|
||||
case FuncExpr::op_port: {
|
||||
Pin *pin = network_->findPin(inst, expr->port());
|
||||
if (pin) {
|
||||
if (pin == input_pin)
|
||||
sense = TimingSense::positive_unate;
|
||||
else
|
||||
sense = TimingSense::none;
|
||||
value = logicValue(pin);
|
||||
}
|
||||
else {
|
||||
sense = TimingSense::none;
|
||||
value = LogicValue::unknown;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FuncExpr::op_not: {
|
||||
TimingSense sense1;
|
||||
LogicValue value1;
|
||||
functionSense(expr->left(), input_pin, inst, sense1, value1);
|
||||
if (value1 == LogicValue::zero) {
|
||||
sense = TimingSense::none;
|
||||
value = LogicValue::one;
|
||||
}
|
||||
else if (value1 == LogicValue::one) {
|
||||
sense = TimingSense::none;
|
||||
value = LogicValue::zero;
|
||||
}
|
||||
else {
|
||||
sense = senseNot(sense1);
|
||||
value = LogicValue::unknown;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FuncExpr::op_or: {
|
||||
TimingSense sense1, sense2;
|
||||
LogicValue value1, value2;
|
||||
functionSense(expr->left(), input_pin, inst, sense1, value1);
|
||||
functionSense(expr->right(), input_pin, inst, sense2, value2);
|
||||
if (value1 == LogicValue::one || value2 == LogicValue::one) {
|
||||
sense = TimingSense::none;
|
||||
value = LogicValue::one;
|
||||
}
|
||||
else if (value1 == LogicValue::zero) {
|
||||
sense = sense2;
|
||||
value = value2;
|
||||
}
|
||||
else if (value2 == LogicValue::zero) {
|
||||
sense = sense1;
|
||||
value = value1;
|
||||
}
|
||||
else {
|
||||
sense = senseAndOr(sense1, sense2);
|
||||
value = LogicValue::unknown;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FuncExpr::op_and: {
|
||||
TimingSense sense1, sense2;
|
||||
LogicValue value1, value2;
|
||||
functionSense(expr->left(), input_pin, inst, sense1, value1);
|
||||
functionSense(expr->right(), input_pin, inst, sense2, value2);
|
||||
if (value1 == LogicValue::zero || value2 == LogicValue::zero) {
|
||||
sense = TimingSense::none;
|
||||
value = LogicValue::zero;
|
||||
}
|
||||
else if (value1 == LogicValue::one) {
|
||||
sense = sense2;
|
||||
value = value2;
|
||||
}
|
||||
else if (value2 == LogicValue::one) {
|
||||
sense = sense1;
|
||||
value = value1;
|
||||
}
|
||||
else {
|
||||
sense = senseAndOr(sense1, sense2);
|
||||
value = LogicValue::unknown;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FuncExpr::op_xor: {
|
||||
TimingSense sense1, sense2;
|
||||
LogicValue value1, value2;
|
||||
functionSense(expr->left(), input_pin, inst, sense1, value1);
|
||||
functionSense(expr->right(), input_pin, inst, sense2, value2);
|
||||
if ((value1 == LogicValue::zero && value2 == LogicValue::zero)
|
||||
|| (value1 == LogicValue::one && value2 == LogicValue::one)) {
|
||||
sense = TimingSense::none;
|
||||
value = LogicValue::zero;
|
||||
}
|
||||
else if ((value1 == LogicValue::zero && value2 == LogicValue::one)
|
||||
|| (value1 == LogicValue::one && value2 == LogicValue::zero)) {
|
||||
sense = TimingSense::none;
|
||||
value = LogicValue::one;
|
||||
}
|
||||
else if (value1 == LogicValue::zero) {
|
||||
sense = sense2;
|
||||
value = value2;
|
||||
}
|
||||
else if (value1 == LogicValue::one) {
|
||||
sense = senseNot(sense2);
|
||||
value = logicNot(value2);
|
||||
}
|
||||
else if (value2 == LogicValue::zero) {
|
||||
sense = sense1;
|
||||
value = value1;
|
||||
}
|
||||
else if (value2 == LogicValue::one) {
|
||||
sense = senseNot(sense1);
|
||||
value = logicNot(value1);
|
||||
}
|
||||
else {
|
||||
sense = senseXor(sense1, sense2);
|
||||
value = logicXor(value1, value2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FuncExpr::op_one:
|
||||
sense = TimingSense::none;
|
||||
value = LogicValue::one;
|
||||
break;
|
||||
case FuncExpr::op_zero:
|
||||
sense = TimingSense::none;
|
||||
value = LogicValue::zero;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LogicValue
|
||||
Sim::evalExpr(const FuncExpr *expr,
|
||||
const Instance *inst)
|
||||
{
|
||||
switch (expr->op()) {
|
||||
case FuncExpr::op_port: {
|
||||
LibertyPort *port = expr->port();
|
||||
if (port) {
|
||||
Pin *pin = network_->findPin(inst, port->name());
|
||||
if (pin)
|
||||
return logicValue(pin);
|
||||
}
|
||||
// Internal ports don't have instance pins.
|
||||
return LogicValue::unknown;
|
||||
}
|
||||
case FuncExpr::op_not:
|
||||
return logicNot(evalExpr(expr->left(), inst));
|
||||
case FuncExpr::op_or:
|
||||
return logicOr(evalExpr(expr->left(),inst),
|
||||
evalExpr(expr->right(),inst));
|
||||
case FuncExpr::op_and:
|
||||
return logicAnd(evalExpr(expr->left(),inst),
|
||||
evalExpr(expr->right(),inst));
|
||||
case FuncExpr::op_xor:
|
||||
return logicXor(evalExpr(expr->left(),inst),
|
||||
evalExpr(expr->right(),inst));
|
||||
case FuncExpr::op_one:
|
||||
return LogicValue::one;
|
||||
case FuncExpr::op_zero:
|
||||
return LogicValue::zero;
|
||||
}
|
||||
// Prevent warnings from lame compilers.
|
||||
return LogicValue::zero;
|
||||
}
|
||||
|
||||
#endif // CUDD
|
||||
|
||||
static LogicValue
|
||||
logicNot(LogicValue value)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,8 +4,6 @@
|
|||
|
||||
#cmakedefine ZLIB_FOUND
|
||||
|
||||
#define CUDD ${CUDD}
|
||||
|
||||
#define SSTA ${SSTA}
|
||||
|
||||
#define TCL_READLINE ${TCL_READLINE}
|
||||
|
|
|
|||
Loading…
Reference in New Issue