#include "spRippleAdderSCDpathBuilder.h" #include "spLeafCellArrayBuilder.h" #include "strtools.h" #include "spPen.h" namespace spp { spRippleAdderSCDpathBuilder::spRippleAdderSCDpathBuilder( std::string instName, spCell* leafCellPtr ) : m_array("fa",leafCellPtr), m_instName(instName), m_leafCellPtr(leafCellPtr), m_bitWidth(1) { } void spRippleAdderSCDpathBuilder::setBitWidth( int bitWidth ) { m_bitWidth = bitWidth; m_array.setDim(1,m_bitWidth); std::string abutLayer = m_leafCellPtr->getTechnology().getValue("abutmentLayer"); assert(abutLayer != string("")); m_array.useAbutmentBox(abutLayer); m_array.flipEvenRows(); m_array.promoteLabelAndPort("A"); m_array.promoteLabelAndPort("B"); m_array.promoteLabelAndPort("S"); m_array.promotePowerNets( "VDD", "VSS" ); } std::string spRippleAdderSCDpathBuilder::getName() const { return m_instName; } sics::box spRippleAdderSCDpathBuilder::getGridDim() const { return sics::box( point(0,0), point(0,m_bitWidth-1) ); } sics::box spRippleAdderSCDpathBuilder::getPlacementBox( sics::point relativeLoc ) const { return m_array.getPlacementBox(relativeLoc); } void spRippleAdderSCDpathBuilder::fixPlacementBox( sics::point relativeLoc, sics::box fixBox ) { sics::box bb = getPlacementBox(relativeLoc); assert((bb.getWidth() == fixBox.getWidth()) && (bb.getHeight() == fixBox.getHeight())); } list spRippleAdderSCDpathBuilder::getPortList( sics::point relativeLoc ) const { return m_array.getPortList(relativeLoc); } sics::box spRippleAdderSCDpathBuilder::getLabelBox( sics::point relPoint, string labelName ) const { return m_array.getLabelBox(relPoint,labelName); } void spRippleAdderSCDpathBuilder::setPortTrack( sics::point relPoint, string pname, int trackAllocation ) { m_array.setPortTrack(relPoint,pname,trackAllocation); } boost::shared_ptr spRippleAdderSCDpathBuilder::clone() const { return boost::shared_ptr(new spRippleAdderSCDpathBuilder(*this)); } void spRippleAdderSCDpathBuilder::genLayout( spCell& targetCell, sics::point loc ) { using namespace strtools; using namespace sics; // Get some technology parameters spTechnology tech = targetCell.getTechnology(); int M2_MIN_WIDTH = strToInt(tech.getValue("spLayer","metal2","minWidth")); int M2_MIN_SPACE = strToInt(tech.getValue("spLayer","metal2","minSpace")); m_array.genLayout(targetCell,loc); // Wire up the carry chain between adder cells spPen carryPen( targetCell, "metal2", "via12", "metal1" ); carryPen.setViaExtensions( spPen::VIA_EXT_LR, spPen::VIA_EXT_LR ); for ( int i = 0; i < m_bitWidth-1; i++ ) { spCellRef& FACell = dynamic_cast(targetCell["fa_"+intToStr(i)+"_"]); spCellRef& nextFACell = dynamic_cast(targetCell["fa_"+intToStr(i+1)+"_"]); point coutPt = FACell.getTransformedLabel("CO").getBoundingBox().getCenter(); point cinPt = FACell.getTransformedLabel("CI").getBoundingBox().getCenter(); point nextCinPt = nextFACell.getTransformedLabel("CI").getBoundingBox().getCenter(); carryPen.moveTo(coutPt); carryPen.drawVia(); int drawDownAbsAmt = coutPt.getY() - M2_MIN_SPACE - M2_MIN_WIDTH; if ( cinPt.getY() < coutPt.getY() ) drawDownAbsAmt = cinPt.getY() - M2_MIN_SPACE - M2_MIN_WIDTH; carryPen.drawDownAbs( drawDownAbsAmt ); carryPen.drawLeft( coutPt.getX() - cinPt.getX() ); carryPen.drawTo( nextCinPt ); carryPen.drawVia(); if ( targetCell.getModulePtr() != 0 ) targetCell.getModulePtr()->wire(FACell.getName()+".CO",nextFACell.getName()+".CI"); } // Wire up first carry in spCellRef& firstFACell = dynamic_cast(targetCell["fa_0_"]); point cinPt = firstFACell.getTransformedLabel("CI").getBoundingBox().getCenter(); point topPt( cinPt.getX(), firstFACell.getBoundingBox().getTopR().getY() ); carryPen.moveTo( cinPt ); carryPen.drawVia(); carryPen.drawTo( topPt ); targetCell.add( spLabel("CI","metal2_pin",topPt) ); if ( targetCell.getModulePtr() != 0 ) { targetCell.getModulePtr()->addPort( "CI", nlst::PORT_IN, 1 ); targetCell.getModulePtr()->wire("CI","fa_0_.CI"); } // Wire up last carry out spCellRef& lastFACell = dynamic_cast(targetCell["fa_"+intToStr(m_bitWidth-1)+"_"]); point coutPt = lastFACell.getTransformedLabel("CO").getBoundingBox().getCenter(); point botPt( coutPt.getX(), lastFACell.getBoundingBox().getBotL().getY() ); carryPen.moveTo( coutPt ); carryPen.drawVia(); carryPen.drawTo( botPt ); targetCell.add( spLabel("CO","metal2_pin",botPt) ); if ( targetCell.getModulePtr() != 0 ) { targetCell.getModulePtr()->addPort( "CO", nlst::PORT_OUT, 1 ); targetCell.getModulePtr()->wire("CO",lastFACell.getName()+".CO"); } } void spRippleAdderSCDpathBuilder::genAbstractModule( nlst::Module& mod ) { mod.addPort( "A", nlst::PORT_IN, m_bitWidth ); mod.addPort( "B", nlst::PORT_IN, m_bitWidth ); mod.addPort( "S", nlst::PORT_OUT, m_bitWidth ); mod.addPort( "CI", nlst::PORT_IN, 1 ); mod.addPort( "CO", nlst::PORT_OUT, 1 ); } }