From b8286315836f607a59ee84328fc8015b856a052f Mon Sep 17 00:00:00 2001 From: Emily Schmidt Date: Thu, 18 Jul 2024 14:23:00 +0100 Subject: [PATCH] functional backend: error out if multiply driven or undriven signals are seen, dont bother putting them in functionalir --- backends/functional/cxx.cc | 1 - backends/functional/smtlib.cc | 5 +---- kernel/functionalir.cc | 14 ++++---------- kernel/functionalir.h | 19 ------------------- 4 files changed, 5 insertions(+), 34 deletions(-) diff --git a/backends/functional/cxx.cc b/backends/functional/cxx.cc index 0fa310164a6..69f1973f2cb 100644 --- a/backends/functional/cxx.cc +++ b/backends/functional/cxx.cc @@ -154,7 +154,6 @@ template struct CxxPrintVisitor : public FunctionalIR::Abstra void state(Node, IdString name) override { print("current_state.{}", state_struct[name]); } void memory_read(Node, Node mem, Node addr) override { print("{}.read({})", mem, addr); } void memory_write(Node, Node mem, Node addr, Node data) override { print("{}.write({}, {})", mem, addr, data); } - void undriven(Node, int width) override { print("Signal<{}>(0)", width); } }; struct CxxModule { diff --git a/backends/functional/smtlib.cc b/backends/functional/smtlib.cc index a2bb6666c3a..d40a4489f6a 100644 --- a/backends/functional/smtlib.cc +++ b/backends/functional/smtlib.cc @@ -180,8 +180,6 @@ struct SmtPrintVisitor : public FunctionalIR::AbstractVisitor { SExpr input(Node, IdString name) override { return input_struct.access("inputs", name); } SExpr state(Node, IdString name) override { return state_struct.access("state", name); } - - SExpr undriven(Node, int width) override { return literal(RTLIL::Const(State::S0, width)); } }; struct SmtModule { @@ -227,8 +225,7 @@ struct SmtModule { list("state", state_struct.name)), list("Pair", output_struct.name, state_struct.name))); auto inlined = [&](FunctionalIR::Node n) { - return n.fn() == FunctionalIR::Fn::constant || - n.fn() == FunctionalIR::Fn::undriven; + return n.fn() == FunctionalIR::Fn::constant; }; SmtPrintVisitor visitor(input_struct, state_struct); auto node_to_sexpr = [&](FunctionalIR::Node n) -> SExpr { diff --git a/kernel/functionalir.cc b/kernel/functionalir.cc index f6d2f556061..155cb3bbc53 100644 --- a/kernel/functionalir.cc +++ b/kernel/functionalir.cc @@ -56,8 +56,6 @@ const char *FunctionalIR::fn_to_string(FunctionalIR::Fn fn) { case FunctionalIR::Fn::constant: return "constant"; case FunctionalIR::Fn::input: return "input"; case FunctionalIR::Fn::state: return "state"; - case FunctionalIR::Fn::multiple: return "multiple"; - case FunctionalIR::Fn::undriven: return "undriven"; case FunctionalIR::Fn::memory_read: return "memory_read"; case FunctionalIR::Fn::memory_write: return "memory_write"; } @@ -75,7 +73,6 @@ struct PrintVisitor : FunctionalIR::DefaultVisitor { std::string constant(Node, RTLIL::Const value) override { return "constant(" + value.as_string() + ")"; } std::string input(Node, IdString name) override { return "input(" + name.str() + ")"; } std::string state(Node, IdString name) override { return "state(" + name.str() + ")"; } - std::string undriven(Node, int width) override { return "undriven(" + std::to_string(width) + ")"; } std::string default_handler(Node self) override { std::string ret = FunctionalIR::fn_to_string(self.fn()); ret += "("; @@ -625,14 +622,11 @@ class FunctionalIRConstruction { factory.suggest_name(node, "$const" + std::to_string(chunk.size()) + "b" + chunk.constant().as_string()); factory.update_pending(pending, node); } else if (chunk.is_multiple()) { - vector args; - for (auto const &driver : chunk.multiple().multiple()) - args.push_back(enqueue(driver)); - Node node = factory.multiple(args, chunk.size()); - factory.update_pending(pending, node); + log_error("Signal %s has multiple drivers. This is not supported by the functional backend. " + "If tristate drivers are used, call tristate -formal to avoid this error.\n", log_signal(chunk)); } else if (chunk.is_none()) { - Node node = factory.undriven(chunk.size()); - factory.update_pending(pending, node); + log_error("The design contains an undriven signal %s. This is not supported by the functional backend. " + "Call setundef with appropriate options to avoid this error.\n", log_signal(chunk)); } else { log_error("unhandled drivespec: %s\n", log_signal(chunk)); log_abort(); diff --git a/kernel/functionalir.h b/kernel/functionalir.h index d0ec1bce6ba..852937612a7 100644 --- a/kernel/functionalir.h +++ b/kernel/functionalir.h @@ -127,12 +127,6 @@ class FunctionalIR { // state(a: IdString): any // returns the current value of the state variable with the specified name state, - // multiple(a: any, b: any, c: any, ...): any - // indicates a value driven by multiple inputs - multiple, - // undriven(width: int): bit[width] - // indicates an undriven value - undriven, // memory_read(memory: memory[addr_width, data_width], addr: bit[addr_width]): bit[data_width] = memory[addr] memory_read, // memory_write(memory: memory[addr_width, data_width], addr: bit[addr_width], data: bit[data_width]): memory[addr_width, data_width] @@ -277,8 +271,6 @@ class FunctionalIR { case Fn::state: return v.state(*this, _ref.function().as_idstring()); break; case Fn::memory_read: return v.memory_read(*this, arg(0), arg(1)); break; case Fn::memory_write: return v.memory_write(*this, arg(0), arg(1), arg(2)); break; - case Fn::multiple: log_error("multiple in visit"); break; - case Fn::undriven: return v.undriven(*this, width()); break; } } std::string to_string(); @@ -319,7 +311,6 @@ class FunctionalIR { virtual T state(Node self, IdString name) = 0; virtual T memory_read(Node self, Node mem, Node addr) = 0; virtual T memory_write(Node self, Node mem, Node addr, Node data) = 0; - virtual T undriven(Node self, int width) = 0; }; // DefaultVisitor provides defaults for all visitor methods which just calls default_handler template struct DefaultVisitor : public AbstractVisitor { @@ -357,7 +348,6 @@ class FunctionalIR { T state(Node self, IdString) override { return default_handler(self); } T memory_read(Node self, Node, Node) override { return default_handler(self); } T memory_write(Node self, Node, Node, Node) override { return default_handler(self); } - T undriven(Node self, int) override { return default_handler(self); } }; // a factory is used to modify a FunctionalIR. it creates new nodes and allows for some modification of existing nodes. class Factory { @@ -475,15 +465,6 @@ class FunctionalIR { _ir.add_state(name, Sort(addr_width, data_width)); return add(NodeData(Fn::state, name), Sort(addr_width, data_width), {}); } - Node multiple(vector args, int width) { - auto node = add(Fn::multiple, Sort(width), {}); - for(const auto &arg : args) - mutate(node).append_arg(arg._ref); - return node; - } - Node undriven(int width) { - return add(Fn::undriven, Sort(width), {}); - } void declare_output(Node node, IdString name, int width) { _ir.add_output(name, Sort(width)); mutate(node).assign_key({name, false});