From 68c3a47945972a685f65620eef73f10c86b87741 Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Mon, 15 Apr 2024 14:14:50 +0200 Subject: [PATCH] WIP temporary drivertools example --- passes/cmds/Makefile.inc | 1 + passes/cmds/example_dt.cc | 140 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 passes/cmds/example_dt.cc diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc index 33e3ae1bc..0918a07df 100644 --- a/passes/cmds/Makefile.inc +++ b/passes/cmds/Makefile.inc @@ -49,3 +49,4 @@ OBJS += passes/cmds/xprop.o OBJS += passes/cmds/dft_tag.o OBJS += passes/cmds/future.o OBJS += passes/cmds/box_derive.o +OBJS += passes/cmds/example_dt.o diff --git a/passes/cmds/example_dt.cc b/passes/cmds/example_dt.cc new file mode 100644 index 000000000..de84fa3cd --- /dev/null +++ b/passes/cmds/example_dt.cc @@ -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 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 queue; + idict 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