Skip to content

Commit

Permalink
Synchronized w/ the main repo.
Browse files Browse the repository at this point in the history
Signed-off-by: Alexander Kamkin <[email protected]>
  • Loading branch information
askamkin committed Feb 2, 2023
1 parent 06b5a1f commit dffcb6a
Show file tree
Hide file tree
Showing 21 changed files with 578 additions and 147 deletions.
2 changes: 1 addition & 1 deletion src/gate/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ add_library(Gate OBJECT
model/gate.cpp
model/gnet.cpp
model/gsymbol.cpp
model/hMetis_formatter.cpp
premapper/aigmapper.cpp
premapper/premapper.cpp
simulator/simulator.cpp
transformer/hmetis.cpp
)
add_library(Utopia::Gate ALIAS Gate)

Expand Down
5 changes: 3 additions & 2 deletions src/gate/debugger/checker.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,16 @@
#include <memory>
#include <unordered_map>

using namespace eda::gate::model;

namespace eda::gate::debugger {

/**
* \brief Implements a logic equivalence checker (LEC).
* \author <a href="mailto:[email protected]">Alexander Kamkin</a>
*/
class Checker final {
using Gate = eda::gate::model::Gate;
using GNet = eda::gate::model::GNet;

public:
using GateBinding = std::unordered_map<Gate::Link, Gate::Link>;
using SubnetBinding = std::unordered_map<GNet::SubnetId, GNet::SubnetId>;
Expand Down
4 changes: 2 additions & 2 deletions src/gate/debugger/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@
#include <cstdint>
#include <unordered_map>

using namespace eda::gate::model;

namespace eda::gate::debugger {

/**
* \brief Logic formula representing a gate-level net.
* \author <a href="mailto:[email protected]">Alexander Kamkin</a>
*/
class Context final {
using Gate = eda::gate::model::Gate;

public:
// MiniSAT-related types.
using Var = Minisat::Var;
Expand Down
2 changes: 2 additions & 0 deletions src/gate/debugger/encoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ void Encoder::encode(const GNet &net, uint16_t version) {
}

void Encoder::encode(const Gate &gate, uint16_t version) {
using GateSymbol = eda::gate::model::GateSymbol;

switch (gate.func()) {
case GateSymbol::IN:
case GateSymbol::OUT:
Expand Down
5 changes: 3 additions & 2 deletions src/gate/debugger/encoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,16 @@
#include <string>
#include <vector>

using namespace eda::gate::model;

namespace eda::gate::debugger {

/**
* \brief Implements a Tseitin encoder of a gate-level netlist.
* \author <a href="mailto:[email protected]">Alexander Kamkin</a>
*/
class Encoder final {
using Gate = eda::gate::model::Gate;
using GNet = eda::gate::model::GNet;

public:
void encode(const GNet &net, uint16_t version);
void encode(const Gate &gate, uint16_t version);
Expand Down
4 changes: 2 additions & 2 deletions src/gate/debugger/symexec.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@
#include "gate/debugger/context.h"
#include "gate/model/gnet.h"

using namespace eda::gate::model;

namespace eda::gate::debugger {

/**
* \brief Implements a symbolic executor of gate-level nets.
* \author <a href="mailto:[email protected]">Alexander Kamkin</a>
*/
class SymbolicExecutor final {
using GNet = eda::gate::model::GNet;

public:
SymbolicExecutor(): _cycle(1 /* should be positive */) {}

Expand Down
8 changes: 8 additions & 0 deletions src/gate/model/gate.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,14 @@ class Gate final : public GateBase {

/// Creates a source gate.
Gate(): Gate(GateSymbol::IN, {}) {}

/// Invariant.
bool invariant() const {
return // Source <=> no inputs.
(isSource() == (arity() == 0))
// Target ==> no outputs.
&& (!isTarget() || (fanout() == 0));
}
};

//===----------------------------------------------------------------------===//
Expand Down
49 changes: 2 additions & 47 deletions src/gate/model/gnet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ GNet::GateId GNet::addGate(Gate *gate, SubnetId sid) {
}

void GNet::setGate(GateId gid, GateSymbol func, const SignalList &inputs) {
// ASSERT: Inputs belong to the net (no need to modify the upper nets).
// ASSERT: All inputs belong to the net (no need to modify the upper nets).
// ASSERT: Adding the given inputs does not lead to combinational cycles.
auto *gate = Gate::get(gid);

Expand All @@ -165,6 +165,7 @@ void GNet::setGate(GateId gid, GateSymbol func, const SignalList &inputs) {

gate->setFunc(func);
gate->setInputs(inputs);
assert(gate->invariant());

std::for_each(subnets.rbegin(), subnets.rend(), [gate](GNet *subnet) {
subnet->onAddGate(gate, true);
Expand Down Expand Up @@ -648,52 +649,6 @@ void GNet::sortTopologically() {
}
}

//===--------------------------------------------------------------------===//
// Cloning
//===--------------------------------------------------------------------===//

/// Clones the net
GNet *GNet::clone() {
if (_gates.empty()) {
return new GNet(_level);
}
std::unordered_map<Gate::Id, Gate::Id> oldToNewId = {};
return clone(oldToNewId);
}

GNet *GNet::clone(std::unordered_map<Gate::Id, Gate::Id> &oldToNewId) {
GNet *resultNet = new GNet(_level);
if (oldToNewId.empty()) {
for (Gate *gate : _gates) {
SignalList newSignals;
Gate *newGate = new Gate(gate->func(), newSignals);
oldToNewId[gate->id()] = newGate->id();
}

for (Gate *gate : _gates) {
SignalList newSignals;
newSignals.reserve(gate->_inputs.capacity());
for (Signal signal : gate->inputs()) {
newSignals.push_back(Signal(signal.event(), oldToNewId[signal.node()]));
}
Gate::Id newGateId = oldToNewId[gate->id()];
Gate::get(newGateId)->setInputs(newSignals);
resultNet->addGate(Gate::get(newGateId));
}
} else {
for (Gate *gate : _gates) {
resultNet->addGate(Gate::get(oldToNewId[gate->id()]));
}
}
if (!_subnets.empty()) {
for (GNet *subnet : _subnets) {
resultNet->addSubnet(subnet->clone(oldToNewId));
}
}

return resultNet;
}

//===----------------------------------------------------------------------===//
// Output
//===----------------------------------------------------------------------===//
Expand Down
152 changes: 144 additions & 8 deletions src/gate/model/gnet.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,43 @@
#include <unordered_set>
#include <vector>

/// Defines the add/set methods for a gate.
#define DEFINE_GATE_METHODS(gateSymbol, addMethod, setMethod)\
GateId addMethod(const SignalList &args) {\
return addGate(gateSymbol, args);\
}\
void setMethod(GateId gid, const SignalList &args) {\
setGate(gid, gateSymbol, args);\
}

/// Defines the add/set methods for a nullary gate.
#define DEFINE_GATE0_METHODS(gateSymbol, addMethod, setMethod)\
GateId addMethod() {\
return addGate(gateSymbol);\
}\
void setMethod(GateId gid) {\
setGate(gid, gateSymbol);\
}

/// Defines the add/set methods for a unary gate.
#define DEFINE_GATE1_METHODS(gateSymbol, addMethod, setMethod)\
template<typename T> GateId addMethod(const T &arg) {\
return addGate(gateSymbol, arg);\
}\
template<typename T> void setMethod(GateId gid, const T &arg) {\
setGate(gid, gateSymbol, arg);\
}

/// Defines the add/set methods for a binary gate.
#define DEFINE_GATE2_METHODS(gateSymbol, addMethod, setMethod)\
DEFINE_GATE_METHODS(gateSymbol, addMethod, setMethod)\
template<typename T> GateId addMethod(const T &lhs, const T &rhs) {\
return addGate(gateSymbol, lhs, rhs);\
}\
template<typename T> void setMethod(GateId gid, const T &lhs, const T &rhs) {\
setGate(gid, gateSymbol, lhs, rhs);\
}

namespace eda::gate::premapper {
class PreMapper;
} // namespace eda::gate::premapper
Expand Down Expand Up @@ -252,6 +289,113 @@ class GNet final {
/// Removes the gate from the net.
void removeGate(GateId gid);

//===--------------------------------------------------------------------===//
// Convenience Methods
//===--------------------------------------------------------------------===//

/// Adds a gate w/o inputs.
GateId addGate(GateSymbol func) {
return addGate(func, SignalList{});
}

/// Changes the given gate to the gate w/o inputs.
void setGate(GateId gid, GateSymbol func) {
setGate(gid, func, SignalList{});
}

/// Adds a single-input gate.
GateId addGate(GateSymbol func, const Signal &arg) {
return addGate(func, SignalList{arg});
}

/// Adds a single-input gate.
GateId addGate(GateSymbol func, GateId arg) {
return addGate(func, Signal::always(arg));
}

/// Changes the given gate to the single-input gate.
void setGate(GateId gid, GateSymbol func, const Signal &arg) {
setGate(gid, func, SignalList{arg});
}

/// Changes the given gate to the single-input gate.
void setGate(GateId gid, GateSymbol func, GateId arg) {
setGate(gid, func, Signal::always(arg));
}

/// Adds a two-inputs gate.
GateId addGate(GateSymbol func, const Signal &lhs, const Signal &rhs) {
return addGate(func, SignalList{lhs, rhs});
}

/// Adds a two-inputs gate.
GateId addGate(GateSymbol func, GateId lhs, GateId rhs) {
return addGate(func, Signal::always(lhs), Signal::always(rhs));
}

/// Changes the given gate to the two-inputs gate.
void setGate(GateId gid, GateSymbol func, const Signal &lhs, const Signal &rhs) {
setGate(gid, func, SignalList{lhs, rhs});
}

/// Changes the given gate to the two-inputs gate.
void setGate(GateId gid, GateSymbol func, GateId lhs, GateId rhs) {
setGate(gid, func, Signal::always(lhs), Signal::always(rhs));
}

DEFINE_GATE0_METHODS(GateSymbol::IN, addIn, setIn)
DEFINE_GATE1_METHODS(GateSymbol::OUT, addOut, setOut)
DEFINE_GATE0_METHODS(GateSymbol::ZERO, addZero, setZero)
DEFINE_GATE0_METHODS(GateSymbol::ONE, addOne, setOne)
DEFINE_GATE1_METHODS(GateSymbol::NOP, addNop, setNop)
DEFINE_GATE1_METHODS(GateSymbol::NOT, addNot, setNot)
DEFINE_GATE2_METHODS(GateSymbol::AND, addAnd, setAnd)
DEFINE_GATE2_METHODS(GateSymbol::OR, addOr, setOr)
DEFINE_GATE2_METHODS(GateSymbol::XOR, addXor, setXor)
DEFINE_GATE2_METHODS(GateSymbol::NAND, addNand, setNand)
DEFINE_GATE2_METHODS(GateSymbol::NOR, addNor, setNor)
DEFINE_GATE2_METHODS(GateSymbol::XNOR, addXnor, setXnor)

/// Adds a LATCH gate.
GateId addLatch(GateId d, GateId ena) {
return addGate(GateSymbol::LATCH, {Signal::always(d), Signal::level1(ena)});
}

/// Changes the given gate to LATCH.
void setLatch(GateId gid, GateId d, GateId ena) {
setGate(gid, GateSymbol::LATCH, {Signal::always(d), Signal::level1(ena)});
}

/// Adds a DFF gate.
GateId addDff(GateId d, GateId clk) {
return addGate(GateSymbol::DFF, {Signal::always(d), Signal::posedge(clk)});
}

/// Changes the given gate to DFF.
void setDff(GateId gid, GateId d, GateId clk) {
setGate(gid, GateSymbol::DFF, {Signal::always(d), Signal::posedge(clk)});
}

/// Adds a DFFrs gate.
GateId addDffrs(GateId d, GateId clk, GateId rst, GateId set) {
return addGate(GateSymbol::DFFrs, {
Signal::always(d),
Signal::posedge(clk),
Signal::level1(rst),
Signal::level1(set)
});
}

/// Changes the given gate to DFFrs.
void setDffrs(GateId gid, GateId d, GateId clk, GateId rst, GateId set) {
setGate(gid, GateSymbol::DFFrs, {
Signal::always(d),
Signal::posedge(clk),
Signal::level1(rst),
Signal::level1(set)
});
}

//===--------------------------------------------------------------------===//
// Subnets
//===--------------------------------------------------------------------===//
Expand Down Expand Up @@ -362,14 +506,6 @@ class GNet final {
/// Sorts the gates in topological order.
void sortTopologically();

//===--------------------------------------------------------------------===//
// Cloning
//===--------------------------------------------------------------------===//

/// Clones the net
GNet* clone();
GNet* clone(std::unordered_map<Gate::Id, Gate::Id> &oldToNewId);

private:
//===--------------------------------------------------------------------===//
// Internal Methods
Expand Down
28 changes: 0 additions & 28 deletions src/gate/model/hMetis_formatter.h

This file was deleted.

Loading

0 comments on commit dffcb6a

Please sign in to comment.