diff --git a/cic-core/src/cells/capcell.cpp b/cic-core/src/cells/capcell.cpp index c95633e..0e224b9 100644 --- a/cic-core/src/cells/capcell.cpp +++ b/cic-core/src/cells/capcell.cpp @@ -37,6 +37,15 @@ namespace cIcCells{ } + void CapCell::usem5(QJsonValue obj){ + if(obj.toInt()){ + usem5_ = true; + }else{ + usem5_ = false; + } + + } + void CapCell::heightIncreaseMult(QJsonValue obj){ heightIncreaseMult_ = obj.toInt(); @@ -97,7 +106,9 @@ namespace cIcCells{ //- First dummy QList rects; - rects.append(new Rect("M5",x- msw ,y , mw, height)); + if(usem5_){ + rects.append(new Rect("M5",x- msw ,y , mw, height)); + } for (auto i =0; imoveTo(x + msw,y + height/2 - ctdumauto->height()); this->add(ctdumauto); @@ -125,7 +143,9 @@ namespace cIcCells{ rects.append(new Rect("M2",x + msw ,y , mw, height)); rects.append(new Rect("M3",x + msw ,y , mw, height)); rects.append(new Rect("M4",x + msw ,y , mw, height)); - rects.append(new Rect("M5",x + msw ,y, mw, height)); + if(usem5_){ + rects.append(new Rect("M5",x + msw ,y, mw, height)); + } xdm = xdm + (msw)*2; } @@ -141,8 +161,11 @@ namespace cIcCells{ auto y16 = y1a + msc*(b - 4); yMax = height; - rects.append(new Rect("M5",xorg - msw, y ,x - xorg + msw*2, mw)); - rects.append(new Rect("M5",xorg - msw, height - mw ,x - xorg + msw*2 , mw)); + if(usem5_){ + rects.append(new Rect("M5",xorg - msw, y ,x - xorg + msw*2, mw)); + rects.append(new Rect("M5",xorg - msw, height - mw ,x - xorg + msw*2 , mw)); + } + auto vss1 = new Rect("M2",xorg, y ,x - xorg +msw, mw); auto ctop1 = new Rect("M4",xorg, y ,x - xorg, mw); diff --git a/cic-core/src/cells/capcell.h b/cic-core/src/cells/capcell.h index 6e794c5..d353f35 100644 --- a/cic-core/src/cells/capcell.h +++ b/cic-core/src/cells/capcell.h @@ -43,6 +43,12 @@ namespace cIcCells{ */ void usem3(QJsonValue obj); + Q_INVOKABLE + /** + * @brief Use Metal 5 shield + */ + void usem5(QJsonValue obj); + Q_INVOKABLE /** * @brief Increase multiplier height @@ -54,6 +60,7 @@ namespace cIcCells{ int xorg = 0; int yMax = 0; bool usem3_ = true; + bool usem5_ = false; int heightIncreaseMult_ = 1; diff --git a/cic-core/src/cells/sar.cpp b/cic-core/src/cells/sar.cpp index f409787..a060816 100644 --- a/cic-core/src/cells/sar.cpp +++ b/cic-core/src/cells/sar.cpp @@ -28,6 +28,15 @@ using namespace cIcCore; namespace cIcCells{ + void SAR::usem5(QJsonValue obj){ + if(obj.toInt()){ + usem5_ = true; + }else{ + usem5_ = false; + } + + } + int SAR::getCellWidth(SARgroup groups, QString group) { int width = 0; @@ -278,13 +287,28 @@ namespace cIcCells{ Rect* r = sarp_cmp[0]; if(r){ - auto ct2 = Cut::getInstance("M4","M5",2,1); + auto ct_cmp =Cut::getInstance("M2","M4",2,1); - auto ct1 =Cut::getInstance("M4","M5",1,2); + Instance * ct2 = nullptr; + Instance * ct1 = nullptr; + if(usem5_){ + ct2 = Cut::getInstance("M4","M5",2,1); + ct1 =Cut::getInstance("M4","M5",1,2); + }else{ + ct2 = Cut::getInstance("M4","M3",2,1); + ct1 =Cut::getInstance("M4","M3",1,2); + } + int ycc = sarp->y2() +ct2->height()*4; auto ra = new Rect("M4",r->x1(),ycc,mw,r->y1()-ycc); ct_cmp->moveTo(r->x1(),r->y1()); - auto rb_cmp = new Rect("M5",ra->x1(),sarp->y1(),mw,ycc-sarp->y1()); + + Rect * rb_cmp = nullptr; + if(usem5_){ + rb_cmp = new Rect("M5",ra->x1(),sarp->y1(),mw,ycc-sarp->y1()); + }else{ + rb_cmp = new Rect("M3",ra->x1(),sarp->y1(),mw,ycc-sarp->y1()); + } ct2->moveTo(ra->x1(),sarp->y1()); ct1->moveTo(ra->x1(),ra->y1()); QList rects = QList() << ct_cmp << rb_cmp << ra << ct2 << ct1<< rb_cmp; @@ -299,16 +323,32 @@ namespace cIcCells{ Rect* r = sarn_cmp[0]; if(r){ - auto ct2 = Cut::getInstance("M4","M5",2,1); + auto ct_cmp =Cut::getInstance("M2","M3",2,1); auto cta_cmp =Cut::getInstance("M3","M4",2,1); - auto ct1 =Cut::getInstance("M4","M5",1,2); + + Instance * ct2 = nullptr; + Instance * ct1 = nullptr; + if(usem5_){ + ct2 = Cut::getInstance("M4","M5",2,1); + ct1 =Cut::getInstance("M4","M5",1,2); + }else{ + ct2 = Cut::getInstance("M4","M3",2,1); + ct1 =Cut::getInstance("M4","M3",1,2); + } + + int ycc = sarp->y2() +ct2->height()*4; auto ra = new Rect("M4",r->x2()+ms,ycc,mw,r->y1()-ycc); cta_cmp->moveTo(r->x2() + ms + mw - ct_cmp->width(),r->y1()); ct_cmp->moveTo(r->x1(),r->y1()); auto rmet = new Rect("M3",ct_cmp->x1(),ct_cmp->y1(),cta_cmp->x2() - ct_cmp->x1(),ct_cmp->height()); - auto rb_cmp = new Rect("M5",ra->x1(),sarn->y1(),mw,ycc-sarn->y1()); + Rect * rb_cmp = nullptr; + if(usem5_){ + rb_cmp = new Rect("M5",ra->x1(),sarn->y1(),mw,ycc-sarn->y1()); + }else{ + rb_cmp = new Rect("M3",ra->x1(),sarn->y1(),mw,ycc-sarn->y1()); + } ct2->moveTo(ra->x1(),sarn->y1()); ct1->moveTo(ra->x1(),ra->y1()); QList rects = QList() << cta_cmp << ct_cmp << rb_cmp << ra << ct2 << ct1<< rb_cmp; diff --git a/cic-core/src/cells/sar.h b/cic-core/src/cells/sar.h index d8b6830..82136f7 100644 --- a/cic-core/src/cells/sar.h +++ b/cic-core/src/cells/sar.h @@ -41,6 +41,12 @@ namespace cIcCells{ virtual void place(); virtual void route(); + + Q_INVOKABLE + /** + * @brief Use Metal 5 shield + */ + void usem5(QJsonValue obj); int getCellWidth(SARgroup groups,QString group); cIcCore::Instance* placeAlternateMirror(SARgroup groups,QString group, int i, int x ,int y, int xoffset); @@ -53,6 +59,7 @@ namespace cIcCells{ Rect* sarn = NULL; Rect* sarp = NULL; + bool usem5_ = true; }; diff --git a/cic-core/src/core/cell.cpp b/cic-core/src/core/cell.cpp index f1c3b9b..b482724 100644 --- a/cic-core/src/core/cell.cpp +++ b/cic-core/src/core/cell.cpp @@ -29,6 +29,7 @@ namespace cIcCore{ _physicalOnly = false; abstract_ = false; lib_cell_ = false; + lib_path_ = ""; cell_used_ = false; _has_pr = false; @@ -580,6 +581,7 @@ namespace cIcCore{ if(o.contains("ckt")){ cIcSpice::Subckt * subckt = new cIcSpice::Subckt(); + subckt->setLibPath(lib_path_); subckt->fromJson(o["ckt"].toObject()); _subckt = subckt; } diff --git a/cic-core/src/core/design.cpp b/cic-core/src/core/design.cpp index 43f703e..a9c16f9 100644 --- a/cic-core/src/core/design.cpp +++ b/cic-core/src/core/design.cpp @@ -285,7 +285,6 @@ namespace cIcCore{ QString to = reg_arr[1].toString(); strlist.replaceInStrings(QRegularExpression(from),to); } - } _spice_parser.parseSubckt(0,strlist); diff --git a/cic-core/src/core/layoutcell.cpp b/cic-core/src/core/layoutcell.cpp index b215d59..ad9182b 100644 --- a/cic-core/src/core/layoutcell.cpp +++ b/cic-core/src/core/layoutcell.cpp @@ -70,12 +70,12 @@ namespace cIcCore{ foreach(QString node, nodeGraphList()){ if(!node.contains(QRegularExpression(regex))) continue; - graphs.append(nodeGraph_[node]); + graphs.append(nodeGraph_[node]); } return graphs; } - void LayoutCell::placeHorizontal(QJsonValue obj){ + void LayoutCell::placeHorizontal(QJsonValue obj){ int hor = obj.toInt(); if(hor> 0){ @@ -803,79 +803,88 @@ namespace cIcCore{ QString location = obj[2].toString(); QString layer = (obj.size() > 3) ? obj[3].toString(): ""; QString options = (obj.size() > 4) ? obj[4].toString(): ""; - this->addRouteConnection(path,includeInstances,layer,location,options); + QString routeTypeOverride = (obj.size() > 5) ? obj[5].toString(): ""; + this->addRouteConnection(path,includeInstances,layer,location,options,routeTypeOverride); } void LayoutCell::addRouteConnection(QString path, QString includeInstances, QString layer, QString location, QString options) { - QString routeType = "-|--"; + this->addRouteConnection(path,includeInstances,layer,location,options,""); + } - if(location == "top"){ - routeType = "||"; - options += ",onTopB,fillvcut"; - }else if(location == "bottom"){ - routeType = "||"; - options += ",onTopT,fillvcut"; - }else if(location == "right"){ - routeType = "-"; - options += ",onTopL,fillhcut"; - }else if( location == "left"){ - options += ",onTopR,fillhcut"; - routeType = "-"; - } + void LayoutCell::addRouteConnection(QString path, QString includeInstances, QString layer, QString location, QString options,QString routeTypeOverride) + { + QString routeType = "-|--"; + if(routeTypeOverride == QString("")){ + if(location == "top"){ + routeType = "||"; + options += ",onTopB,fillvcut"; + }else if(location == "bottom"){ + routeType = "||"; + options += ",onTopT,fillvcut"; + }else if(location == "right"){ + routeType = "-"; + options += ",onTopL,fillhcut"; + }else if( location == "left"){ + options += ",onTopR,fillhcut"; + routeType = "-"; + } + }else{ + routeType = routeTypeOverride; + } - foreach(QString node, nodeGraphList()){ + foreach(QString node, nodeGraphList()){ - if(!node.contains(QRegularExpression(path))) continue; - if(!named_rects_.contains("rail_" + node)) continue; + if(!node.contains(QRegularExpression(path))) continue; + if(!named_rects_.contains("rail_" + node)) continue; - Graph * g = nodeGraph_[node]; - QList rects = g->getRectangles("",includeInstances,layer); - RouteRing* rr = static_cast(named_rects_["rail_" + node]); - if(rr){ - Rect* routering = rr->get(location); - QList empty; + Graph * g = nodeGraph_[node]; + QList rects = g->getRectangles("",includeInstances,layer); + RouteRing* rr = static_cast(named_rects_["rail_" + node]); + if(rr){ + Rect* routering = rr->get(location); + QList empty; - foreach(Rect* r, rects){ - QList stop; - stop.append(r); - stop.append(routering); - Route* ro = new Route(node,layer,empty,stop,options,routeType); - routes_.append(ro); - rr->add(ro); + foreach(Rect* r, rects){ + QList stop; + stop.append(r); + stop.append(routering); + Route* ro = new Route(node,layer,empty,stop,options,routeType); + routes_.append(ro); + rr->add(ro); + } } - } - } - } + } + } - void LayoutCell::trimRouteRing(QJsonArray obj) - { + void LayoutCell::trimRouteRing(QJsonArray obj) + { - if(obj.size() < 3){ - qDebug() << "Error: trimRouteRings must contain at least 3 element\n"; - return; + if(obj.size() < 3){ + qDebug() << "Error: trimRouteRings must contain at least 3 element\n"; + return; + } + QString path = obj[0].toString(); + QString location = obj[1].toString(); + QString whichEndToTrim = obj[2].toString(); + this->trimRouteRing(path,location,whichEndToTrim); } - QString path = obj[0].toString(); - QString location = obj[1].toString(); - QString whichEndToTrim = obj[2].toString(); - this->trimRouteRing(path,location,whichEndToTrim); - } - void LayoutCell::trimRouteRing(QString path, QString location,QString whichEndToTrim) - { - QList rects = this->getChildren("cIcCore::RouteRing"); - foreach(Rect* r,rects){ + void LayoutCell::trimRouteRing(QString path, QString location,QString whichEndToTrim) + { + QList rects = this->getChildren("cIcCore::RouteRing"); + foreach(Rect* r,rects){ - RouteRing* rr = static_cast(r); + RouteRing* rr = static_cast(r); - if(rr->name().contains(QRegularExpression(path))){ + if(rr->name().contains(QRegularExpression(path))){ - rr->trimRouteRing(location,whichEndToTrim); + rr->trimRouteRing(location,whichEndToTrim); + } } } - } @@ -886,359 +895,364 @@ namespace cIcCore{ // Internal functions //------------------------------------------------------------------------------------------ - QStringList LayoutCell::expandBus(QString name){ + QStringList LayoutCell::expandBus(QString name){ - QStringList names; - QRegularExpression re_bus("<(\\d+):(\\d+)>"); - QRegularExpressionMatch m_bus = re_bus.match(name); - if(m_bus.hasMatch()){ + QStringList names; + QRegularExpression re_bus("<(\\d+):(\\d+)>"); + QRegularExpressionMatch m_bus = re_bus.match(name); + if(m_bus.hasMatch()){ - QString start = m_bus.captured(1); - QString stop = m_bus.captured(2); - int istart = start.toInt(); - int istop = stop.toInt(); - for(int i=istart;i>=istop;i=i-1){ - names.append(name.replace(QRegularExpression("<.*>"),QString("<%1>").arg(i))); + QString start = m_bus.captured(1); + QString stop = m_bus.captured(2); + int istart = start.toInt(); + int istop = stop.toInt(); + for(int i=istart;i>=istop;i=i-1){ + names.append(name.replace(QRegularExpression("<.*>"),QString("<%1>").arg(i))); + } + }else{ + names.append(name); } - }else{ - names.append(name); + return names; } - return names; - } - - void LayoutCell::place(){ - QString prev_group = ""; + void LayoutCell::place(){ - int next_x = 0; - int next_y = 0; + QString prev_group = ""; - int x = 0; - int y = 0; - bool mirror_y = false; - if(!_subckt) return; + int next_x = 0; + int next_y = 0; + int x = 0; + int y = 0; + bool mirror_y = false; + if(!_subckt) return; - foreach(cIcSpice::SubcktInstance * ckt_inst,_subckt->instances()){ - QString group = ckt_inst->groupName(); - if(_placeHorizontal){ - y = 0; - x = next_x; - } + foreach(cIcSpice::SubcktInstance * ckt_inst,_subckt->instances()){ + QString group = ckt_inst->groupName(); - if(prev_group.compare(group) != 0 && prev_group.compare("") != 0){ + if(prev_group.compare(group) != 0 && prev_group.compare("") != 0){ - if(!_placeHorizontal){ - y = 0; - x = next_x; + if(!_placeHorizontal){ + y = 0; + x = next_x; + }else{ + x = 0; + y = next_y; + } + mirror_y = !mirror_y; } - mirror_y = !mirror_y; - } - prev_group = group; + prev_group = group; - int instance_x = x; - int instance_y = y; + int instance_x = x; + int instance_y = y; - if(ckt_inst->hasProperty("xoffset")){ - QString offset = ckt_inst->getPropertyString("xoffset"); - if(offset == "width") - { - //Not implemented - }else{ - int xoffset = offset.toInt(); - instance_x = instance_x + this->rules->get("ROUTE","horizontalgrid")*xoffset; + if(ckt_inst->hasProperty("xoffset")){ + QString offset = ckt_inst->getPropertyString("xoffset"); + if(offset == "width") + { + //Not implemented + }else{ + int xoffset = offset.toInt(); + instance_x = instance_x + this->rules->get("ROUTE","horizontalgrid")*xoffset; + } } - } - if(ckt_inst->hasProperty("yoffset")){ - QString offset = ckt_inst->getPropertyString("yoffset"); + if(ckt_inst->hasProperty("yoffset")){ + QString offset = ckt_inst->getPropertyString("yoffset"); - if(offset == "height"){ - //Not implemented - }else{ - int yoffset = offset.toInt(); - instance_y = instance_y + this->rules->get("ROUTE","verticalgrid")*yoffset; + if(offset == "height"){ + //Not implemented + }else{ + int yoffset = offset.toInt(); + instance_y = instance_y + this->rules->get("ROUTE","verticalgrid")*yoffset; + } } - } - Instance* inst = this->addInstance(ckt_inst,instance_x,instance_y); + Instance* inst = this->addInstance(ckt_inst,instance_x,instance_y); - if(ckt_inst->hasProperty("angle")){ - QString angle = ckt_inst->getPropertyString("angle"); - if(angle == "180"){ - inst->setAngle("MY"); - } + if(ckt_inst->hasProperty("angle")){ + QString angle = ckt_inst->getPropertyString("angle"); + if(angle == "180"){ + inst->setAngle("MY"); + } + + if(angle == "MX"){ + inst->setAngle("MX"); + + } - if(angle == "MX"){ - inst->setAngle("MX"); } - } + if(alternateGroup_ && mirror_y){ + inst->setAngle("MY"); - if(alternateGroup_ && mirror_y){ - inst->setAngle("MY"); + }else if(alternateGroup_ && !mirror_y){ + } - }else if(alternateGroup_ && !mirror_y){ + next_x = inst->x2(); + next_y = inst->y2(); - } + if(!_placeHorizontal){ + x = inst->x1(); + if(useHalfHeight){ + y += (inst->y2() - instance_y)/2; + }else{ + y = next_y; + } + }else{ + x = next_x; + y = inst->y1(); + } - next_x = inst->x2(); - next_y = inst->y2(); - x = inst->x1(); - if(useHalfHeight){ - y += (inst->y2() - instance_y)/2; - }else{ - y = next_y; } - } - this->updateBoundingRect(); + this->updateBoundingRect(); - } + } - Instance* LayoutCell::addInstance(cIcSpice::SubcktInstance* ckt_inst, int x, int y) - { + Instance* LayoutCell::addInstance(cIcSpice::SubcktInstance* ckt_inst, int x, int y) + { - //The chain of events is important here, ports get defined in the setSubckInstance - Instance * inst = Instance::getInstance(ckt_inst->subcktName()); - inst->setSubcktInstance(ckt_inst); - this->add(inst); - Text * t = new Text(ckt_inst->name()); - t->moveTo( inst->width()/2, inst->height()/2); - inst->add(t); - inst->moveTo(x,y); - this->addToNodeGraph(inst); - return inst; - } + //The chain of events is important here, ports get defined in the setSubckInstance + Instance * inst = Instance::getInstance(ckt_inst->subcktName()); + inst->setSubcktInstance(ckt_inst); + this->add(inst); + Text * t = new Text(ckt_inst->name()); + t->moveTo( inst->width()/2, inst->height()/2); + inst->add(t); + inst->moveTo(x,y); + this->addToNodeGraph(inst); + return inst; + } - void LayoutCell::addToNodeGraph(Instance * inst){ + void LayoutCell::addToNodeGraph(Instance * inst){ - if(inst == NULL) return; + if(inst == NULL) return; - auto allp = inst->allports(); - auto keys = inst->allPortNames(); + auto allp = inst->allports(); + auto keys = inst->allPortNames(); - foreach(QString s, keys){ + foreach(QString s, keys){ - foreach(Port * p,allp[s]){ - if(p == NULL) continue; - if(nodeGraph_.contains(p->name())){ + foreach(Port * p,allp[s]){ + if(p == NULL) continue; + if(nodeGraph_.contains(p->name())){ - nodeGraph_[p->name()]->append(p); + nodeGraph_[p->name()]->append(p); - }else{ - Graph *g = new Graph(); - g->name = p->name(); - g->append(p); - nodeGraphList_.append(p->name()); - nodeGraph_[p->name()] = g; - } + }else{ + Graph *g = new Graph(); + g->name = p->name(); + g->append(p); + nodeGraphList_.append(p->name()); + nodeGraph_[p->name()] = g; + } + } } - } - } + } - QList LayoutCell::nodeGraphList() - { + QList LayoutCell::nodeGraphList() + { - return nodeGraphList_; + return nodeGraphList_; - } + } - void LayoutCell::route(){ - foreach(Rect *r, routes_){ - if(r->isRoute()){ - Route * route = static_cast(r); - route->route(); + void LayoutCell::route(){ + foreach(Rect *r, routes_){ + if(r->isRoute()){ + Route * route = static_cast(r); + route->route(); + } } - } - - } - void LayoutCell::paint(){ - if(!noPowerRoute_){ - this->routePower(); } - Cell::paint(); - } - - QList LayoutCell::findRectanglesByNode(QString node, QString filterChild, QString matchInstance) - { - QList rects; - foreach(Rect * r, this->children()){ - if(!r->isInstance()) continue; - Instance * i = static_cast(r); - if(i == NULL){continue;} - - if(matchInstance != "" && !i->name().contains(QRegularExpression(matchInstance))){continue;} - QList childRects = i->findRectanglesByNode(node, filterChild); - foreach(Rect *r, childRects){ - rects.append(r); + void LayoutCell::paint(){ + if(!noPowerRoute_){ + this->routePower(); } - } - return rects; - - } - void LayoutCell::addPowerRoute(QString net,QString excludeInstances) - { - QList foundrects = this->findRectanglesByNode(net,"^(B|G|BULKP|BULKN)$", ""); - - QList rects; - foreach(Rect * r, foundrects){ - Rect * parent = r->parent(); - if(parent && parent->isCell() ){ - Cell *c = static_cast(parent); - QString name = c->name(); - bool skip = false; - - if(excludeInstances != "" && c->isInstance()){ - Instance* i = static_cast(c); - QString lname = i->name(); - QString instName = i->instanceName(); - if(lname.contains(QRegularExpression(excludeInstances))) skip = true; - if(instName.contains(QRegularExpression(excludeInstances))) skip = true; - } + Cell::paint(); + } - if(!skip) + QList LayoutCell::findRectanglesByNode(QString node, QString filterChild, QString matchInstance) + { + QList rects; + foreach(Rect * r, this->children()){ + if(!r->isInstance()) continue; + Instance * i = static_cast(r); + if(i == NULL){continue;} + + if(matchInstance != "" && !i->name().contains(QRegularExpression(matchInstance))){continue;} + QList childRects = i->findRectanglesByNode(node, filterChild); + foreach(Rect *r, childRects){ rects.append(r); - - }else{ - rects.append(r); + } } + return rects; } - //TODO: If there are multiple rectangles horizontally this - //method makes a sheet, should really make it better - if(rects.length() > 0){ - QList cuts = Cut::getCutsForRects("M4",rects,2,1); - Rect * rp = NULL; - if(cuts.count() > 0){ - Rect r= Cell::calcBoundingRect(cuts,false); - r.setTop(this->top()); - r.setBottom(this->bottom()); - r.setLayer("M4"); - this->add(cuts); + void LayoutCell::addPowerRoute(QString net,QString excludeInstances) + { + QList foundrects = this->findRectanglesByNode(net,"^(B|G|BULKP|BULKN)$", ""); + + QList rects; + foreach(Rect * r, foundrects){ + Rect * parent = r->parent(); + if(parent && parent->isCell() ){ + Cell *c = static_cast(parent); + QString name = c->name(); + bool skip = false; + + if(excludeInstances != "" && c->isInstance()){ + Instance* i = static_cast(c); + QString lname = i->name(); + QString instName = i->instanceName(); + if(lname.contains(QRegularExpression(excludeInstances))) skip = true; + if(instName.contains(QRegularExpression(excludeInstances))) skip = true; + } + + if(!skip) + rects.append(r); + + }else{ + rects.append(r); + } - rp = new Rect(r); - }else{ - Rect r= Cell::calcBoundingRect(rects,false); - r.setTop(this->top()); - r.setBottom(this->bottom()); - r.setLayer("M4"); - rp = new Rect(r); } - if(rp){ - this->add(rp); - if(ports_.contains(net)){ - Port * p = ports_[net]; - p->set(rp); + + //TODO: If there are multiple rectangles horizontally this + //method makes a sheet, should really make it better + if(rects.length() > 0){ + QList cuts = Cut::getCutsForRects("M4",rects,2,1); + Rect * rp = NULL; + if(cuts.count() > 0){ + Rect r= Cell::calcBoundingRect(cuts,false); + r.setTop(this->top()); + r.setBottom(this->bottom()); + r.setLayer("M4"); + this->add(cuts); + + rp = new Rect(r); + }else{ + Rect r= Cell::calcBoundingRect(rects,false); + r.setTop(this->top()); + r.setBottom(this->bottom()); + r.setLayer("M4"); + rp = new Rect(r); + } + if(rp){ + this->add(rp); + if(ports_.contains(net)){ + Port * p = ports_[net]; + p->set(rp); + } } } } - } - void LayoutCell::fromJson(QJsonObject o){ - Cell::fromJson(o); + void LayoutCell::fromJson(QJsonObject o){ + Cell::fromJson(o); - this->updateBoundingRect(); + this->updateBoundingRect(); - this->useHalfHeight = o["useHalfHeight"].toBool(); - this->alternateGroup_ = o["alternateGroup"].toBool(); - this->noPowerRoute_ = o["noPowerRoute"].toBool(); - } + this->useHalfHeight = o["useHalfHeight"].toBool(); + this->alternateGroup_ = o["alternateGroup"].toBool(); + this->noPowerRoute_ = o["noPowerRoute"].toBool(); + } - Rect * LayoutCell::cellFromJson(QJsonObject co){ + Rect * LayoutCell::cellFromJson(QJsonObject co){ - auto c = Cell::cellFromJson(co); + auto c = Cell::cellFromJson(co); - if(c == 0){ - QString cl = co["class"].toString(); - if(cl == "Instance"){ - Instance * i = new Instance(); - i->fromJson(co); - this->addToNodeGraph(i); - return i; - }else if(cl== "cIcCore::LayoutCell" || cl== "cIcCore::Route" || cl == "cIcCore::RouteRing" || cl == "cIcCore::Guard" ){ + if(c == 0){ + QString cl = co["class"].toString(); + if(cl == "Instance"){ + Instance * i = new Instance(); + i->fromJson(co); + this->addToNodeGraph(i); + return i; + }else if(cl== "cIcCore::LayoutCell" || cl== "cIcCore::Route" || cl == "cIcCore::RouteRing" || cl == "cIcCore::Guard" ){ - LayoutCell * l = new LayoutCell(); - l->fromJson(co); - return l; - }else{ - qDebug() << "Could not read class " << cl; - return 0; + LayoutCell * l = new LayoutCell(); + l->fromJson(co); + return l; + }else{ + qDebug() << "Could not read class " << cl; + return 0; + } } - } - return c; - } + return c; + } - void LayoutCell::routePower(){ - this->addPowerRoute("AVDD","NCH|DMY"); - this->addPowerRoute("AVSS","PCH|DMY"); - } + void LayoutCell::routePower(){ + this->addPowerRoute("AVDD","NCH|DMY"); + this->addPowerRoute("AVSS","PCH|DMY"); + } - void LayoutCell::addAllPorts(){ - if(!_subckt) return; - QStringList nodes = _subckt->nodes(); + void LayoutCell::addAllPorts(){ + if(!_subckt) return; + QStringList nodes = _subckt->nodes(); - QString filterChild = "^B$"; - QString filterInstance = ""; - foreach(QString node,nodes){ + QString filterChild = "^B$"; + QString filterInstance = ""; + foreach(QString node,nodes){ - if(ports_.contains(node)) continue; + if(ports_.contains(node)) continue; - QList rects = this->findRectanglesByNode("^" + node+"$",filterChild,filterInstance); + QList rects = this->findRectanglesByNode("^" + node+"$",filterChild,filterInstance); - if(rects.count() > 0){ - this->updatePort(node,rects[0]); + if(rects.count() > 0){ + this->updatePort(node,rects[0]); - }else{ - qDebug() << "Error: No rects found on " <useHalfHeight; - o["alternateGroup"] = this->alternateGroup_; - o["noPowerRoute"] = this->noPowerRoute_; + QJsonObject LayoutCell::toJson(){ + QJsonObject o = Cell::toJson(); + o["useHalfHeight"] = this->useHalfHeight; + o["alternateGroup"] = this->alternateGroup_; + o["noPowerRoute"] = this->noPowerRoute_; - QJsonArray graph; - foreach(QString node, nodeGraphList()){ - Graph * g = nodeGraph_[node]; - graph.append(g->toJson()); + QJsonArray graph; + foreach(QString node, nodeGraphList()){ + Graph * g = nodeGraph_[node]; + graph.append(g->toJson()); + } + o["graph"] = graph; + + return o; } - o["graph"] = graph; - return o; } - -} diff --git a/cic-core/src/core/layoutcell.h b/cic-core/src/core/layoutcell.h index 54dbed9..847e75b 100644 --- a/cic-core/src/core/layoutcell.h +++ b/cic-core/src/core/layoutcell.h @@ -129,6 +129,7 @@ namespace cIcCore{ void addPowerRing(QString layer, QString name, QString location, int widthmult,int spacemult); void addPowerConnection(QString name, QString includeInstances, QString location); void addRouteConnection(QString path, QString includeInstances, QString layer, QString location, QString options); + void addRouteConnection(QString path, QString includeInstances, QString layer, QString location, QString options,QString routeTypeOverride); Instance* getInstanceFromInstanceName(QString instanceName); diff --git a/cic-core/src/core/patterntile.cpp b/cic-core/src/core/patterntile.cpp index d3bf515..ffaac80 100644 --- a/cic-core/src/core/patterntile.cpp +++ b/cic-core/src/core/patterntile.cpp @@ -60,7 +60,14 @@ namespace cIcCore { y2 += verticalMultiplyVectorSum(ymax_)*(double)yspace_; - //qDebug() << "Bounding pattern" << x1 << y1 << x2 << y2 << ymax_ << verticalMultiplyVector_.count(); + //There is an error when ymax_ == 0 + //TODO: Look at the boundary, I think there is a think error on ymax + //The below is a bandaid + if(ymax_ == 0){ + y2 = (double)yspace_; + } + + //qDebug() << "Bounding pattern" << x1 << y1 << x2 << y2 << ymax_ << verticalMultiplyVector_.count() << widthoffset_ << heightoffset_; Rect r; r.setPoint1(x1,y1); @@ -371,16 +378,11 @@ namespace cIcCore { currentHeightDelta_ = currentHeight_ - yspace_; int ys = translateY(y); - - for(int x=0;x <= xmax_;x++){ QString s = strs[strs.length() - y -1]; - - - if((s.length()-1) < x){ qDebug() << "Error: To few columns in " << s; } @@ -408,7 +410,6 @@ namespace cIcCore { currentHeight_ = yspace_*vmv; } - if(c == 'X' || polyWidthAdjust_ == 0){ currentHeight_ = yspace_*vmv; } diff --git a/cic-core/src/core/patterntile.h b/cic-core/src/core/patterntile.h index 8044189..e57d885 100644 --- a/cic-core/src/core/patterntile.h +++ b/cic-core/src/core/patterntile.h @@ -181,7 +181,7 @@ namespace cIcCore{ /** * @brief Adjust the poly width - * @accessors polyWidthAdjustg(), setPolyWidthAdjust() + * @accessors polyWidthAdjust(), setPolyWidthAdjust() **/ Q_PROPERTY(int polyWidthAdjust READ polyWidthAdjust WRITE setPolyWidthAdjust) diff --git a/cic-core/src/printer/cics.cpp b/cic-core/src/printer/cics.cpp index bfc8520..b17e376 100644 --- a/cic-core/src/printer/cics.cpp +++ b/cic-core/src/printer/cics.cpp @@ -34,8 +34,6 @@ namespace cIcPrinter{ void Cics::startLib(QString name) { DesignPrinter::startLib(name); - - } void Cics::endLib() @@ -43,7 +41,6 @@ namespace cIcPrinter{ QTextStream ts(&file); QJsonDocument d(ar); - ts << d.toJson(); DesignPrinter::endLib(); diff --git a/cic-core/src/spice/subckt.h b/cic-core/src/spice/subckt.h index cb417a2..2c37f27 100644 --- a/cic-core/src/spice/subckt.h +++ b/cic-core/src/spice/subckt.h @@ -53,6 +53,8 @@ namespace cIcSpice{ void parse(QList buffer, int line); QList instances(){ return _instances;} QList devices(){ return _devices;} + void setLibPath(QString path){_lib_path = path; } + QString libPath(){return _lib_path;} void add(SubcktInstance* s) { @@ -86,6 +88,7 @@ namespace cIcSpice{ QHash _inst_index; QList _instances; QList _devices; + QString _lib_path; }; diff --git a/cic-gui/src/cellpainter.cpp b/cic-gui/src/cellpainter.cpp index c73b723..1545f5b 100644 --- a/cic-gui/src/cellpainter.cpp +++ b/cic-gui/src/cellpainter.cpp @@ -143,8 +143,13 @@ namespace cIcPainter{ QColor color(l->color); + QPen pen = QPen(color,Qt::SolidLine); + + //Use 50 Ångstrøm for the width + pen.setWidth(50); color.setAlpha(150); - painter.setPen(QPen(color,Qt::SolidLine)); + painter.setPen(pen); + //Set pattern and fill Qt::BrushStyle bstyle = Qt::SolidPattern; @@ -163,12 +168,15 @@ namespace cIcPainter{ void CellPainter::startCell(QPainter & painter,Cell *c){ if(Cell::isEmpty(c)) return; + this->paintRect(painter,c); + } void CellPainter::endCell(QPainter & painter){ + } - void CellPainter::paint(QPainter & painter, Cell *c, int x, int y,int width, int height,QString instanceName) + /* void CellPainter::paint(QPainter & painter, Cell *c, int x, int y,int width, int height,QString instanceName) { _instanceName = instanceName ; @@ -191,7 +199,9 @@ namespace cIcPainter{ painter.scale(1,-1); painter.translate(0,-height); painter.translate(x,y); - painter.drawRect(c->x1(),c->y1(),c->width(),c->height()); + qDebug() << "Painting " << c->name(); + this->paintRect(painter,c); + //painter.drawRect(c->x1(),c->y1(),c->width(),c->height()); this->paintCell(painter,c,""); @@ -204,7 +214,7 @@ namespace cIcPainter{ this->paint(painter,c,x,y,width,height,""); } - +*/ void CellPainter::paintCell(QPainter & painter,Cell * c,QString hierarchy){ diff --git a/cic-gui/src/cellpainter.h b/cic-gui/src/cellpainter.h index 64aeea6..ef0b77f 100644 --- a/cic-gui/src/cellpainter.h +++ b/cic-gui/src/cellpainter.h @@ -50,8 +50,8 @@ namespace cIcPainter{ virtual void paintPort(QPainter &painter,Port *); virtual void paintText(QPainter &painter,Text *); - virtual void paint(QPainter &painter, Cell *,int x, int y, int width, int height,QString instanceName); - virtual void paint(QPainter &painter, Cell *,int x, int y, int width, int height); + //virtual void paint(QPainter &painter, Cell *,int x, int y, int width, int height,QString instanceName); + //virtual void paint(QPainter &painter, Cell *,int x, int y, int width, int height); virtual void paintCell(QPainter &painter, Cell *,QString hierarchy); virtual void paintRect(QPainter &painter, Rect * rect); virtual void paintReference(QPainter &painter,Instance *,QString hiearchy); diff --git a/etc/mac_sdk.pro b/etc/mac_sdk.pro index 41bcd59..70377af 100644 --- a/etc/mac_sdk.pro +++ b/etc/mac_sdk.pro @@ -2,7 +2,7 @@ mac { #- This needs to point to the SDK usually in /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ #CONFIG += sdk - EXPORT_QMAKE_MAC_SDK = macosx14.2 + EXPORT_QMAKE_MAC_SDK = macosx14.4 #QT_MAC_SDK_NO_VERSION_CHECK = 1 }