Search code examples
c++treeverilog

How to turn verilog gate-level code to C++ tree representation?


module circuit(input a1, b1, d1, d2, output OUT);

wire a, b, c, d, e, f;

NOT A(a, a1);
NOT B(b, b1);
NOT C(c, a);
NAND D(d, d1, d2);
NAND E(e, b, c);
NAND F(f, d, e);
NOT G(OUT, f);


endmodule

Is there any method that is able to convert the above code to tree(in the attached the image shows the tree I want to convert to)?

I don't know if there's efficient way to construct the tree, and I have searched on the net, but didn't find relative ideas.


Solution

  • The Verilog syntax looks similar to C++ so you could try to shoehorn it into proper C++ although I doubt it would be a good idea :-D :

    #include <vector>
    #include <iostream>
    
    enum class Op {
      NOT, NAND
    };
    
    struct wire {
      std::vector<wire*> inputs;
      Op op;
    
      bool constantValue = false;
    
      bool evaluate() {
        if (inputs.empty()) {
          return constantValue;
        } else if (op == Op::NOT) {
          return !inputs[0]->evaluate();
        } else if (op == Op::NAND) {
          return !(inputs[0]->evaluate() && inputs[1]->evaluate());
        } else {
          return false;
        }
      }
    };
    
    class NOT {
    public:
      NOT(wire& dst, wire& src) {
        dst.op = Op::NOT;
        dst.inputs.push_back(&src);
      }
    };
    
    class NAND {
    public:
      NAND(wire& dst, wire& a, wire& b) {
        dst.op = Op::NAND;
        dst.inputs.push_back(&a);
        dst.inputs.push_back(&b);
      }
    };
    
    #define module
    #define endmodule
    #define output
    #define input
    #define circuit(...) wire __VA_ARGS__
    

    and then just insert the code in a C++ function.

    int main()
    {
      module circuit(input a1, b1, d1, d2, output OUT);
    
      wire a, b, c, d, e, f;
    
      NOT A(a, a1);
      NOT B(b, b1);
      NOT C(c, a);
      NAND D(d, d1, d2);
      NAND E(e, b, c);
      NAND F(f, d, e);
      NOT G(OUT, f);
    
      endmodule
    
      std::cout << "The result of OUT = " << OUT.evaluate() << std::endl;
        
      return 0;
    }
    

    Instances of the wire class will point at other wire instances from the inputs member variable, thereby forming a "tree". Is that what you ask for?