text: /*****************************************************************************
   *                                McPAT/CACTI
   *                      SOFTWARE LICENSE AGREEMENT
   *            Copyright 2012 Hewlett-Packard Development Company, L.P.
   *                          All Rights Reserved
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions are
   * met: redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer;
   * redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in the
   * documentation and/or other materials provided with the distribution;
   * neither the name of the copyright holders nor the names of its
   * contributors may be used to endorse or promote products derived from
   * this software without specific prior written permission.
  
   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.”
   *
   ***************************************************************************/
  
  
  #ifndef __DECODER_H__
  #define __DECODER_H__
  
  #include <vector>
  
  #include "area.h"
  #include "component.h"
  #include "parameter.h"
  
  using namespace std;
  
  
  class Decoder : public Component
  {
    public:
      Decoder(
          int _num_dec_signals,
          bool flag_way_select,
          double _C_ld_dec_out,
          double _R_wire_dec_out,
          bool fully_assoc_,
          bool is_dram_,
          bool is_wl_tr_,
          const Area & cell_);
  
      bool   exist;
      int    num_in_signals;
      double C_ld_dec_out;
      double R_wire_dec_out;
      int    num_gates;
      int    num_gates_min;
      double w_dec_n[MAX_NUMBER_GATES_STAGE];
      double w_dec_p[MAX_NUMBER_GATES_STAGE];
      double delay;
      //powerDef power;
      bool   fully_assoc;
      bool   is_dram;
      bool   is_wl_tr;
      const  Area & cell;
  
  
      void   compute_widths();
      void   compute_area();
      double compute_delays(double inrisetime);  // return outrisetime
  
      void leakage_feedback(double temperature);
  };
  
  
  
  class PredecBlk : public Component
  {
   public:
    PredecBlk(
        int num_dec_signals,
        Decoder * dec,
        double C_wire_predec_blk_out,
        double R_wire_predec_blk_out,
        int    num_dec_per_predec,
        bool   is_dram_,
        bool   is_blk1);
  
    Decoder * dec;
    bool exist;
    int number_input_addr_bits;
    double C_ld_predec_blk_out;
    double R_wire_predec_blk_out;
    int branch_effort_nand2_gate_output;
    int branch_effort_nand3_gate_output;
    bool   flag_two_unique_paths;
    int flag_L2_gate;
    int number_inputs_L1_gate;
    int number_gates_L1_nand2_path;
    int number_gates_L1_nand3_path;
    int number_gates_L2;
    int min_number_gates_L1;
    int min_number_gates_L2;
    int num_L1_active_nand2_path;
    int num_L1_active_nand3_path;
    double w_L1_nand2_n[MAX_NUMBER_GATES_STAGE];
    double w_L1_nand2_p[MAX_NUMBER_GATES_STAGE];
    double w_L1_nand3_n[MAX_NUMBER_GATES_STAGE];
    double w_L1_nand3_p[MAX_NUMBER_GATES_STAGE];
    double w_L2_n[MAX_NUMBER_GATES_STAGE];
    double w_L2_p[MAX_NUMBER_GATES_STAGE];
    double delay_nand2_path;
    double delay_nand3_path;
    powerDef power_nand2_path;
    powerDef power_nand3_path;
    powerDef power_L2;
  
    bool is_dram_;
  
    void compute_widths();
    void compute_area();
  
    void leakage_feedback(double temperature);
  
    pair<double, double> compute_delays(pair<double, double> inrisetime); // <nand2, nand3>
    // return <outrise_nand2, outrise_nand3>
  };
  
  
  class PredecBlkDrv : public Component
  {
   public:
    PredecBlkDrv(
        int   way_select,
        PredecBlk * blk_,
        bool  is_dram);
  
    int flag_driver_exists;
    int number_input_addr_bits;
    int number_gates_nand2_path;
    int number_gates_nand3_path;
    int min_number_gates;
    int num_buffers_driving_1_nand2_load;
    int num_buffers_driving_2_nand2_load;
    int num_buffers_driving_4_nand2_load;
    int num_buffers_driving_2_nand3_load;
    int num_buffers_driving_8_nand3_load;
    int num_buffers_nand3_path;
    double c_load_nand2_path_out;
    double c_load_nand3_path_out;
    double r_load_nand2_path_out;
    double r_load_nand3_path_out;
    double width_nand2_path_n[MAX_NUMBER_GATES_STAGE];
    double width_nand2_path_p[MAX_NUMBER_GATES_STAGE];
    double width_nand3_path_n[MAX_NUMBER_GATES_STAGE];
    double width_nand3_path_p[MAX_NUMBER_GATES_STAGE];
    double delay_nand2_path;
    double delay_nand3_path;
    powerDef power_nand2_path;
    powerDef power_nand3_path;
  
    PredecBlk * blk;
    Decoder   * dec;
    bool  is_dram_;
    int   way_select;
  
    void compute_widths();
    void compute_area();
  
    void leakage_feedback(double temperature);
  
  
    pair<double, double> compute_delays(
        double inrisetime_nand2_path,
        double inrisetime_nand3_path);  // return <outrise_nand2, outrise_nand3>
  
    inline int num_addr_bits_nand2_path()
    {
      return num_buffers_driving_1_nand2_load +
             num_buffers_driving_2_nand2_load +
             num_buffers_driving_4_nand2_load;
    }
    inline int num_addr_bits_nand3_path()
    {
      return num_buffers_driving_2_nand3_load +
             num_buffers_driving_8_nand3_load;
    }
    double get_rdOp_dynamic_E(int num_act_mats_hor_dir);
  };
  
  
  
  class Predec : public Component
  {
    public:
      Predec(
          PredecBlkDrv * drv1,
          PredecBlkDrv * drv2);
  
      double compute_delays(double inrisetime);  // return outrisetime
  
      void leakage_feedback(double temperature);
      PredecBlk    * blk1;
      PredecBlk    * blk2;
      PredecBlkDrv * drv1;
      PredecBlkDrv * drv2;
  
      powerDef block_power;
      powerDef driver_power;
  
    private:
      // returns <delay, risetime>
      pair<double, double> get_max_delay_before_decoder(
          pair<double, double> input_pair1,
          pair<double, double> input_pair2);
  };
  
  
  
  class Driver : public Component
  {
   public:
    Driver(double c_gate_load_, double c_wire_load_, double r_wire_load_, bool is_dram);
  
    int    number_gates;
    int    min_number_gates;
    double width_n[MAX_NUMBER_GATES_STAGE];
    double width_p[MAX_NUMBER_GATES_STAGE];
    double c_gate_load;
    double c_wire_load;
    double r_wire_load;
    double delay;
    powerDef power;
    bool   is_dram_;
  
    void   compute_widths();
    double compute_delay(double inrisetime);
  };
  
  
  #endif
  