//-----------------------------------------------------------------------------
// Ripple Carry Adder Standard Cell Datapath Builder
//
// Works with leaf cells which are correctly labeled with 
// "A", "B", "CI", "CO", "S" ports.
//

#ifndef SP_RIPPLE_ADDER_SCDPATH_BUILDER_H
#define SP_RIPPLE_ADDER_SCDPATH_BUILDER_H

#include "spLeafCellArrayBuilder.h"
#include "boost/shared_ptr.hpp"
#include "spPrimitives.h"
#include "spDpathGenerator.h"
#include "sics.h"
#include <string>

namespace spp {

  class spRippleAdderSCDpathBuilder : public spDpathBuilder {

   public:
    spRippleAdderSCDpathBuilder( std::string instName, spCell* leafCellPtr );
    ~spRippleAdderSCDpathBuilder() { }

    // Bitwidth is set by grid 
    void setBitWidth( int bitwidth );

    // All builders have unique names. If the builder is wrapped when
    // it generates layout then the generated spCellRef will have the
    // builder's name prefixed by a "x"
    std::string getName() const;

    // Grid dim is how much of the datapath builder's grid this builder
    // wants to be responsible for.
    sics::box getGridDim() const;

    // Return the placement box for an element that this builder
    // is responsible for
    sics::box getPlacementBox( sics::point relativeLoc ) const;

    // Fix the placement box for an element that this builder is responsible
    // for. Since this builder uses fixed leaf cells and doesn't know how to
    // do extensions, calling this with anything other than the builder's
    // actual placement box will cause an assertion
    void fixPlacementBox( sics::point relativeLoc, sics::box fixBox );

    // Return a list of ports which need to be routed using the datapath
    // generator for an element that this builder is responsible for.
    list<string> getPortList( sics::point relativeLoc ) const;

    // Return the location of a label for an element that this builder
    // is responsible for. Note that this might not be the final location
    // until genLayout() is called. After genLaout() this definitely 
    // should return the actual location.
    sics::box getLabelBox( sics::point relPoint, string labelName ) const;

    // Tells this builder that the port with the given pname (for the given
    // element) has been allocated by the datapath generator to the 
    // given trackAllocation. The track allocation is an relative offset from
    // the bottom of the abutment box.
    void setPortTrack( sics::point relPoint, string pname, int trackAllocation );

    // Return a copy of this builder.
    boost::shared_ptr<spBuilder> clone() const;

    // This builder does indeed return netlist information if the given
    // target cell has an attached netlist module.
    bool producesNetlist() const { return true; }

    // Actually generate the layout in the given target cell at the give
    // location. The location should be where the lower left hand of the
    // placement box should appear in the targetCell
    void genLayout( spCell& targetCell, sics::point loc = sics::point(0,0) );

    // Add ports to the given module which describes the abstract interface
    // of this builder.
    void genAbstractModule( nlst::Module& mod );

   private:    
    spLeafCellArrayBuilder m_array;
    std::string m_instName;
    spCell* m_leafCellPtr;
    int m_bitWidth;

  };

}

#endif

