verilog_ir.h 5.39 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
/*!
 *  Copyright (c) 2017 by Contributors
 * \file verilog_ir.h
 * \brief A lowered IR that resembles verilog blocks,
 *   This is data structure before final codegen.
 */
#ifndef TVM_CODEGEN_VERILOG_VERILOG_IR_H_
#define TVM_CODEGEN_VERILOG_VERILOG_IR_H_

#include <tvm/ir.h>
#include <tvm/expr.h>
#include <tvm/channel.h>
#include <tvm/lowered_func.h>
#include <vector>
#include <memory>
#include <unordered_map>

namespace tvm {
namespace codegen {
namespace verilog {

/*! \brief The data argument type */
enum StageInputType : int {
  /*! \brief Data channel input. */
  kChannel,
  /*! \brief Loop variable generated by compute block. */
  kLoopVar,
  /*! \brief Global constant. */
  kGlobalConst
};

/*! \brief The data argument type */
enum ControlSignalType : int {
  // Read advance signal
  kReadAdvance,
  // Write advance signal
  kWriteAdvance,
  // Pipeline stage finish signal
  kComputeFinish
};

class ControlSignal;
class StageInput;
class SignalTrigger;

/*! \brief The control signal of a channel */
struct ControlSignalNode : public Node {
  /*! \brief The control signal type */
  ControlSignalType ctrl_type;
  /*! \brief Advance size of the signal */
  int advance_size{0};
  // visit all attributes
  void VisitAttrs(AttrVisitor* v) final {
    v->Visit("ctrl_type", &ctrl_type);
    v->Visit("advance_size", &advance_size);
  }
  static ControlSignal make(ControlSignalType ctrl_type, int advance_size);
  static constexpr const char* _type_key = "VerilogControlSignal";
  TVM_DECLARE_NODE_TYPE_INFO(ControlSignalNode, Node);
};

TVM_DEFINE_NODE_REF(ControlSignal, ControlSignalNode);

/*! \brief Information about channel. */
struct ChannelBlockNode : public Node {
  /*! \brief The channel we are refer to */
  Channel channel;
  /*! \brief Read window */
  int read_window{0};
  /*! \brief Write window */
  int write_window{0};
  /*! \brief Control signals in the channel */
  Array<ControlSignal> ctrl_signals;
  // visit all attributes
  void VisitAttrs(AttrVisitor* v) final {
    v->Visit("channel", &channel);
    v->Visit("read_window", &read_window);
    v->Visit("write_window", &write_window);
    v->Visit("ctrl_signals", &ctrl_signals);
  }
  static constexpr const char* _type_key = "VerilogChannelBlock";
  TVM_DECLARE_NODE_TYPE_INFO(ChannelBlockNode, Node);
};

TVM_DEFINE_NODE_REF(ChannelBlock, ChannelBlockNode);

/*!
 * \brief Input to the compute block.
 *  These represents the data values that need to be shared;
 */
struct StageInputNode : public Node {
  /*!
   * \brief The corresponding var of the input
   *  For loop and global const it is the var.
   *  For channel this corresponds to the channel handle.
   */
  Var var;
  /*! \brief The type of the input. */
  StageInputType input_type;
  // visit all attributes
  void VisitAttrs(AttrVisitor* v) final {
    v->Visit("var", &var);
    v->Visit("input_type", &input_type);
  }
  // constructor
  static StageInput make(Var var, StageInputType input_type);
  static constexpr const char* _type_key = "VerilogStageInput";
  TVM_DECLARE_NODE_TYPE_INFO(StageInputNode, Node);
};

TVM_DEFINE_NODE_REF(StageInput, StageInputNode);

/*! \brief The trigger signal for certain channel */
struct SignalTriggerNode : public Node {
  /*! \brief The channel handle variable */
  Var channel_var;
  /*! \brief Boolean predicate to trigger the signal */
  Expr predicate;
  /*! \brief siginal index of the channel */
  int signal_index;
  // visit all attributes
  void VisitAttrs(AttrVisitor* v) final {
    v->Visit("channel_var", &channel_var);
    v->Visit("predicate", &predicate);
    v->Visit("signal_index", &signal_index);
  }
  // constructor
  static constexpr const char* _type_key = "VerilogSignalTrigger";
  TVM_DECLARE_NODE_TYPE_INFO(SignalTriggerNode, Node);
};

TVM_DEFINE_NODE_REF(SignalTrigger, SignalTriggerNode);

/*! \brief compute block for verilog */
struct ComputeBlockNode : public Node {
  /*! \brief The body of the block. */
  Stmt body;
  /*! \brief The loop nest around the body, each is a For with no_op as body */
  Array<Stmt> loop;
  /*! \brief The channel advance trigger */
  Array<SignalTrigger> triggers;
  /*! \brief The input variables that need to be synced. */
  Map<Var, StageInput> inputs;
  // visit all attributes
  void VisitAttrs(AttrVisitor* v) final {
    v->Visit("body", &body);
    v->Visit("loop", &loop);
    v->Visit("triggers", &triggers);
    v->Visit("inputs", &inputs);
  }

  static constexpr const char* _type_key = "VerilogComputeBlock";
  TVM_DECLARE_NODE_TYPE_INFO(ComputeBlockNode, Node);
};

TVM_DEFINE_NODE_REF(ComputeBlock, ComputeBlockNode);

/*! \brief Codeblock for verilog module. */
struct PipelineNode : public Node {
  /*! \brief arguments to the module */
  Array<Var> args;
  /*! \brief Computation stages */
  Array<ComputeBlock> stages;
  /*! \brief The data channels */
  Map<Var, ChannelBlock> channels;

  // visit all attributes
  void VisitAttrs(AttrVisitor* v) final {
    v->Visit("args", &args);
    v->Visit("stages", &stages);
    v->Visit("channels", &channels);
  }
  static constexpr const char* _type_key = "VerilogPipeline";
  TVM_DECLARE_NODE_TYPE_INFO(PipelineNode, Node);
};

TVM_DEFINE_NODE_REF(Pipeline, PipelineNode);

/*!
 * \brief Build a lowered verilog pipeline given function.
 * \param f The function to be transformed.
 * \param The created verilog pipeline.
 */
Pipeline MakePipeline(LoweredFunc f);
}  // namespace verilog
}  // namespace codegen
}  // namespace tvm
#endif  // TVM_CODEGEN_VERILOG_VERILOG_IR_H_