Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions src/db/db/dbLayout.cc
Original file line number Diff line number Diff line change
Expand Up @@ -707,14 +707,12 @@ Layout::set_technology_name (const std::string &tech)

for (db::Layout::iterator c = begin (); c != end (); ++c) {

std::map<db::lib_id_type, db::lib_id_type>::const_iterator m;

db::LibraryProxy *lib_proxy = dynamic_cast<db::LibraryProxy *> (&*c);
if (! lib_proxy) {
continue;
}

if ((m = mapping.find (lib_proxy->lib_id ())) != mapping.end ()) {
if (mapping.find (lib_proxy->lib_id ()) != mapping.end ()) {

db::Library *lib = db::LibraryManager::instance ().lib (lib_proxy->lib_id ());
db::Cell *lib_cell = &lib->layout ().cell (lib_proxy->library_cell_index ());
Expand Down Expand Up @@ -745,7 +743,10 @@ Layout::set_technology_name (const std::string &tech)
db::cell_index_type ci = lp->first->Cell::cell_index ();
db::PCellVariant *lib_pcell = lp->second;

std::pair<bool, pcell_id_type> pn = lib_pcell->layout ()->pcell_by_name (lp->first->get_basic_name ().c_str ());
db::Library *new_lib = db::LibraryManager::instance ().lib (mapping [lp->first->lib_id ()]);
tl_assert (new_lib != 0);

std::pair<bool, pcell_id_type> pn = new_lib->layout ().pcell_by_name (lp->first->get_basic_name ().c_str ());

if (! pn.first) {

Expand All @@ -756,8 +757,6 @@ Layout::set_technology_name (const std::string &tech)

} else {

db::Library *new_lib = db::LibraryManager::instance ().lib (mapping [lp->first->lib_id ()]);

const db::PCellDeclaration *old_pcell_decl = lib_pcell->layout ()->pcell_declaration (lib_pcell->pcell_id ());
const db::PCellDeclaration *new_pcell_decl = new_lib->layout ().pcell_declaration (pn.second);
if (! old_pcell_decl || ! new_pcell_decl) {
Expand Down
1 change: 1 addition & 0 deletions src/rba/unit_tests/rbaTests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ RUBYTEST (dbNetlistReaderTests, "dbNetlistReaderTests.rb")
RUBYTEST (dbNetlistCompare, "dbNetlistCompare.rb")
RUBYTEST (dbPathTest, "dbPathTest.rb")
RUBYTEST (dbPCells, "dbPCells.rb")
RUBYTEST (dbPCellsRebind, "dbPCellsRebind.rb")
RUBYTEST (dbPointTest, "dbPointTest.rb")
RUBYTEST (dbPolygonTest, "dbPolygonTest.rb")
RUBYTEST (dbRegionTest, "dbRegionTest.rb")
Expand Down
202 changes: 202 additions & 0 deletions testdata/ruby/dbPCellsRebind.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
# encoding: UTF-8

# KLayout Layout Viewer
# Copyright (C) 2006-2026 Matthias Koefferlein
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

if !$:.member?(File::dirname($0))
$:.push(File::dirname($0))
end

load("test_prologue.rb")

class PCellRebindVar < RBA::PCellDeclaration

def initialize(name, layer, w_name, w_default)
@name = name
@layer = layer
@w_name = w_name
@w_default = w_default
end

def display_text(parameters)
return "#{@name}(L=#{@layer},#{@w_name}=#{parameters[0].to_s},H=#{parameters[1].to_s})"
end

def get_parameters

# prepare a set of parameter declarations
param = []

param.push(RBA::PCellParameterDeclaration.new(@w_name, RBA::PCellParameterDeclaration::TypeDouble, "Width", @w_default))
param.push(RBA::PCellParameterDeclaration.new("H", RBA::PCellParameterDeclaration::TypeDouble, "Height", 1.0))

return param

end

def get_layers(parameters)
return [ RBA::LayerInfo::new(@layer, 0) ]
end

def produce(layout, layers, parameters, cell)

# fetch the parameters
w = parameters[0]
h = parameters[1]

# create the shape
cell.shapes(layout.layer(@layer, 0)).insert(RBA::DBox.new(-w / 2, -h / 2, w / 2, h / 2))

end

end

class RebindTestLib < RBA::Library

def initialize(var)

# set the description
self.description = "PCell rebind test lib"

# create the PCell declarations
if var == 0
layout.register_pcell("Box0", PCellRebindVar::new("Box0", 0, "W", 3.0))
layout.register_pcell("Box1", PCellRebindVar::new("Box1", 1, "W", 2.0))
layout.register_pcell("Box2A", PCellRebindVar::new("Box2A", 2, "W", 1.0))
else
layout.register_pcell("Box2B", PCellRebindVar::new("Box2B", 12, "W", 1.5))
layout.register_pcell("Box1", PCellRebindVar::new("Box1", 11, "WW", 2.5))
layout.register_pcell("Box0", PCellRebindVar::new("Box0", 10, "W", 3.5))
end

self.technology = (var == 0 ? "T0" : "T1")

register("RebindTestLib")

end

end

def c2s(cell)
ly = cell.layout
s = []
ly.layer_indexes.collect { |li| ly.get_info(li) }.sort { |a,b| [ a.layer, a.datatype ] <=> [ b.layer, b.datatype ] }.each do |lp|
bbox = cell.dbbox(ly.layer(lp))
bbox.empty? || (s << lp.to_s + ":" + bbox.to_s)
end
s.join(";")
end

class DBPCellRebind_TestClass < TestBase

def test_1

tl0 = RebindTestLib::new(0)
tl1 = RebindTestLib::new(1)

assert_equal(tl0.is_for_technology("T0"), true)
assert_equal(tl0.is_for_technology("T1"), false)
assert_equal(tl1.is_for_technology("T0"), false)
assert_equal(tl1.is_for_technology("T1"), true)

ly = RBA::Layout::new
ly.technology_name = "T0"

top = ly.create_cell("TOP")

# in T0:
# Box0 -> on layer 0, w parameter is "W" with default 3.0
# Box1 -> on layer 1, w parameter is "W" with default 2.0
# Box2A -> on layer 2, w parameter is "W" with default 1.0
# Box2B does not exist

c0 = ly.create_cell("Box0", "RebindTestLib", { "W" => 0.3, "H" => 0.5 })
c1 = ly.create_cell("Box1", "RebindTestLib", { "W" => 0.4, "H" => 0.6 })
c2 = ly.create_cell("Box2A", "RebindTestLib", { "W" => 0.5, "H" => 0.7 })

top.insert(RBA::CellInstArray::new(c0.cell_index(), RBA::Trans::new))
top.insert(RBA::CellInstArray::new(c1.cell_index(), RBA::Trans::new))
top.insert(RBA::CellInstArray::new(c2.cell_index(), RBA::Trans::new))

assert_equal(c0.display_title, "RebindTestLib.Box0(L=0,W=0.3,H=0.5)")
assert_equal(c2s(c0), "0/0:(-0.15,-0.25;0.15,0.25)")

assert_equal(c1.display_title, "RebindTestLib.Box1(L=1,W=0.4,H=0.6)")
assert_equal(c2s(c1), "1/0:(-0.2,-0.3;0.2,0.3)")

assert_equal(c2.display_title, "RebindTestLib.Box2A(L=2,W=0.5,H=0.7)")
assert_equal(c2s(c2), "2/0:(-0.25,-0.35;0.25,0.35)")

# in T0:
# Box0 -> on layer 0, w parameter is "W" with default 3.5
# Box1 -> on layer 1, w parameter is "WW" with default 2.5
# Box2A does not exist
# Box2B -> on layer 2, w parameter is "W" with default 1.5

ly.technology_name = "T1"

assert_equal(c0.destroyed, false)
assert_equal(c1.destroyed, false)
assert_equal(c2.destroyed, true) # becomes a cold proxy

c0 = ly.cell("Box0")
c1 = ly.cell("Box1")
c2 = ly.cell("Box2A")

# layer changed, but parameters can be translated
assert_equal(c0.display_title, "RebindTestLib.Box0(L=10,W=0.3,H=0.5)")
assert_equal(c2s(c0), "10/0:(-0.15,-0.25;0.15,0.25)")

# Layer changed and "W" parameter can't be translated as the name changed to "WW"
assert_equal(c1.display_title, "RebindTestLib.Box1(L=11,WW=2.5,H=0.6)")
assert_equal(c2s(c1), "11/0:(-1.25,-0.3;1.25,0.3)")

# Box2A does no longer exist -> cold proxy
assert_equal(c2.display_title, "<defunct>RebindTestLib.Box2A")
assert_equal(c2s(c2), "2/0:(-0.25,-0.35;0.25,0.35)")

ly.technology_name = "T0"

assert_equal(c0.destroyed, false)
assert_equal(c1.destroyed, false)
assert_equal(c2.destroyed, true) # became an active PCell variant again

c0 = ly.cell("Box0")
c1 = ly.cell("Box1")
c2 = ly.cell("Box2A")

# layer changed, but parameters can be translated
assert_equal(c0.display_title, "RebindTestLib.Box0(L=0,W=0.3,H=0.5)")
assert_equal(c2s(c0), "0/0:(-0.15,-0.25;0.15,0.25)")

# Layer changed and "WW" parameter can't be translated as the name changed back to "W"
assert_equal(c1.display_title, "RebindTestLib.Box1(L=1,W=2.0,H=0.6)")
assert_equal(c2s(c1), "1/0:(-1,-0.3;1,0.3)")

# Box2A is back to normal as the cold proxy kept the information
assert_equal(c2.display_title, "RebindTestLib.Box2A(L=2,W=0.5,H=0.7)")
assert_equal(c2s(c2), "2/0:(-0.25,-0.35;0.25,0.35)")

tl0._destroy
tl1._destroy

end

end

load("test_epilogue.rb")

Loading