mirror of https://github.com/YosysHQ/yosys.git
WIP temporary drivertools example
This commit is contained in:
parent
56572978f5
commit
68c3a47945
|
@ -49,3 +49,4 @@ OBJS += passes/cmds/xprop.o
|
||||||
OBJS += passes/cmds/dft_tag.o
|
OBJS += passes/cmds/dft_tag.o
|
||||||
OBJS += passes/cmds/future.o
|
OBJS += passes/cmds/future.o
|
||||||
OBJS += passes/cmds/box_derive.o
|
OBJS += passes/cmds/box_derive.o
|
||||||
|
OBJS += passes/cmds/example_dt.o
|
||||||
|
|
|
@ -0,0 +1,140 @@
|
||||||
|
#include "kernel/yosys.h"
|
||||||
|
#include "kernel/drivertools.h"
|
||||||
|
#include "kernel/topo_scc.h"
|
||||||
|
|
||||||
|
USING_YOSYS_NAMESPACE
|
||||||
|
PRIVATE_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct ExampleWorker
|
||||||
|
{
|
||||||
|
DriverMap dm;
|
||||||
|
Module *module;
|
||||||
|
|
||||||
|
ExampleWorker(Module *module) : module(module) {
|
||||||
|
dm.celltypes.setup();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ExampleDtPass : public Pass
|
||||||
|
{
|
||||||
|
ExampleDtPass() : Pass("example_dt", "drivertools example") {}
|
||||||
|
|
||||||
|
void help() override
|
||||||
|
{
|
||||||
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
log("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||||
|
{
|
||||||
|
size_t argidx = 1;
|
||||||
|
extra_args(args, argidx, design);
|
||||||
|
|
||||||
|
for (auto module : design->selected_modules()) {
|
||||||
|
ExampleWorker worker(module);
|
||||||
|
DriverMap dm;
|
||||||
|
|
||||||
|
dm.add(module);
|
||||||
|
|
||||||
|
idict<DriveSpec> queue;
|
||||||
|
idict<Cell *> cells;
|
||||||
|
|
||||||
|
IntGraph edges;
|
||||||
|
|
||||||
|
|
||||||
|
for (auto cell : module->cells()) {
|
||||||
|
if (cell->type.in(ID($assert), ID($assume), ID($cover), ID($check)))
|
||||||
|
queue(DriveBitMarker(cells(cell), 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto wire : module->wires()) {
|
||||||
|
if (!wire->port_output)
|
||||||
|
continue;
|
||||||
|
queue(DriveChunk(DriveChunkWire(wire, 0, wire->width)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define emit log
|
||||||
|
// #define emit(X...) do {} while (false)
|
||||||
|
|
||||||
|
for (int i = 0; i != GetSize(queue); ++i)
|
||||||
|
{
|
||||||
|
emit("n%d: ", i);
|
||||||
|
DriveSpec spec = queue[i];
|
||||||
|
if (spec.chunks().size() > 1) {
|
||||||
|
emit("concat %s <-\n", log_signal(spec));
|
||||||
|
for (auto const &chunk : spec.chunks()) {
|
||||||
|
emit(" * %s\n", log_signal(chunk));
|
||||||
|
edges.add_edge(i, queue(chunk));
|
||||||
|
}
|
||||||
|
} else if (spec.chunks().size() == 1) {
|
||||||
|
DriveChunk chunk = spec.chunks()[0];
|
||||||
|
if (chunk.is_wire()) {
|
||||||
|
DriveChunkWire wire_chunk = chunk.wire();
|
||||||
|
if (wire_chunk.is_whole()) {
|
||||||
|
if (wire_chunk.wire->port_input) {
|
||||||
|
emit("input %s\n", log_signal(spec));
|
||||||
|
} else {
|
||||||
|
DriveSpec driver = dm(DriveSpec(wire_chunk));
|
||||||
|
edges.add_edge(i, queue(driver));
|
||||||
|
emit("wire driver %s <- %s\n", log_signal(spec), log_signal(driver));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
DriveChunkWire whole_wire(wire_chunk.wire, 0, wire_chunk.width);
|
||||||
|
edges.add_edge(i, queue(whole_wire));
|
||||||
|
emit("wire slice %s <- %s\n", log_signal(spec), log_signal(DriveSpec(whole_wire)));
|
||||||
|
}
|
||||||
|
} else if (chunk.is_port()) {
|
||||||
|
DriveChunkPort port_chunk = chunk.port();
|
||||||
|
if (port_chunk.is_whole()) {
|
||||||
|
if (dm.celltypes.cell_output(port_chunk.cell->type, port_chunk.port)) {
|
||||||
|
int cell_marker = queue(DriveBitMarker(cells(port_chunk.cell), 0));
|
||||||
|
if (!port_chunk.cell->type.in(ID($dff), ID($ff)))
|
||||||
|
edges.add_edge(i, cell_marker);
|
||||||
|
emit("cell output %s %s\n", log_id(port_chunk.cell), log_id(port_chunk.port));
|
||||||
|
} else {
|
||||||
|
DriveSpec driver = dm(DriveSpec(port_chunk));
|
||||||
|
edges.add_edge(i, queue(driver));
|
||||||
|
emit("cell port driver %s <- %s\n", log_signal(spec), log_signal(driver));
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
DriveChunkPort whole_port(port_chunk.cell, port_chunk.port, 0, GetSize(port_chunk.cell->connections().at(port_chunk.port)));
|
||||||
|
edges.add_edge(i, queue(whole_port));
|
||||||
|
emit("port slice %s <- %s\n", log_signal(spec), log_signal(DriveSpec(whole_port)));
|
||||||
|
}
|
||||||
|
} else if (chunk.is_constant()) {
|
||||||
|
emit("constant %s <- %s\n", log_signal(spec), log_const(chunk.constant()));
|
||||||
|
} else if (chunk.is_marker()) {
|
||||||
|
Cell *cell = cells[chunk.marker().marker];
|
||||||
|
emit("cell %s %s\n", log_id(cell->type), log_id(cell));
|
||||||
|
for (auto const &conn : cell->connections()) {
|
||||||
|
if (!dm.celltypes.cell_input(cell->type, conn.first))
|
||||||
|
continue;
|
||||||
|
emit(" * %s <- %s\n", log_id(conn.first), log_signal(conn.second));
|
||||||
|
edges.add_edge(i, queue(DriveChunkPort(cell, conn)));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log_abort();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log_abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
topo_sorted_sccs(edges, [&](int *begin, int *end) {
|
||||||
|
emit("scc:");
|
||||||
|
for (int *i = begin; i != end; ++i)
|
||||||
|
emit(" n%d", *i);
|
||||||
|
emit("\n");
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
log("Plugin test passed!\n");
|
||||||
|
}
|
||||||
|
} ExampleDtPass;
|
||||||
|
|
||||||
|
PRIVATE_NAMESPACE_END
|
Loading…
Reference in New Issue