It looks like you're new here. If you want to get involved, click one of these buttons!
I've been having some issues with grid bumping up and
down (probably due to fat-fingering the bindkeys, unaware).
So I have cell instances and polygon interconnect that are
now placed at a variety of grids and it's a bit ugly.
I've looked for, but not found, any "snap to grid" utility
that I would use to get everything on the 1.0u grid again.
I only find mention of snapping as a piece of other functions'
activity in the forum. There is nothing about a snap function
for objects in the manual, only Rulers.
Wonder if someone has a macro script for this perhaps?
All I really want to do is strip decimal places (rounding to
closest, would be acceptable but not strictly necessary) in
object origin / vertices, but not by hand one object at a time.
Comments
Hi Jim,
DRC has a snapping feature, but that will flatten your layer and turn all paths and boxes into polygons and remove texts.
A dirty trick is to save your layout with 1 µm database unit and later with a finer DBU again. This will force snapping, but beware of manifold snap artefacts.
Matthias
Hi Jim,
A long time ago I made the example below when working my way into Ruby and scripting. The code is most likely not the "cleanest" but it works for me. Note that it is not recursive and the vectors of instance arrays are also put on grid (you might want to resolve instance arrays first).
Cheers,
Tomas
module MyMacro
Puts selected shapes (boxes, polygons and paths) and instances (origin and array parameters on a user-defined grid.
This function is NOT recursive.
include RBA
app = Application.instance
mw = app.main_window
lv = mw.current_view
cv = lv.active_cellview
ly = cv.layout
dbu = ly.dbu
ok = Value.new(true)
grid = QInputDialog.getDouble(mw, "getDouble()", "Value", 0.1, dbu, 10, 5, ok)
if ok.value
begin
lv.transaction("Put selected objects on grid")
if lv == nil
raise "Shape Statistics: No view selected"
end
grid_dbu = grid/dbu
instances_to_modify = []
shapes_to_modify = []
lv.each_object_selected do |sel|
end
instances_to_modify.each do |instance|
instance = instance.inst
trans0 = instance.trans
text = instance.trans.to_s
text2 = text.gsub(",", "\s").split("\s")
px = text2[1].to_i
py = text2[2].to_i
point1 = Point.new(-px,-py)
trans1 = Trans.new(point1)
px = ((px/grid_dbu).round.to_igrid_dbu).to_i
py = ((py/grid_dbu).round.to_igrid_dbu).to_i
point2 = Point.new(px,py)
trans2 = Trans.new(point2)
instance.trans=trans2trans1trans0
a = instance.a
b = instance.b
ax = a.x
ay = a.y
bx = b.x
by = b.y
ax = ((ax/grid_dbu).round.to_igrid_dbu).to_i
ay = ((ay/grid_dbu).round.to_igrid_dbu).to_i
bx = ((bx/grid_dbu).round.to_igrid_dbu).to_i
by = ((by/grid_dbu).round.to_igrid_dbu).to_i
a = Point.new(ax,ay)
b = Point.new(bx,by)
instance.a=(a)
instance.b=(b)
end
shapes_to_modify.each do |shape|
if shape.shape.is_box?
elsif shape.shape.is_polygon?
polygonnew = Polygon.new(hull)
polygon.polygon=polygonnew
elsif shape.shape.is_path?
width = path.path.width
width = ((width/2/grid_dbu).round.to_i*grid_dbu).to_i * 2
bgn_ext = path.path.bgn_ext
end_ext = path.path.end_ext
is_round = path.path.is_round?
pathnew = Path.new(points, width, bgn_ext, end_ext, is_round)
path.path=pathnew
end
end
ensure
lv.commit
end
end
end
Hi Thomas,
if you want to achieve readability, you can put a triple backtick line in front of and after your code. Then the code will be formatted as such (markdown). See http://en.wikipedia.org/wiki/Markdown for details.
Kind regards,
Matthias
Hi Matthias,
Thanks for the tip, could not edit, so re-post below...
Very good ... that's better to read :-)
I think something is wrong at the beginning (make sure the initial line is only three backticks). But that's just a small flaw.
I tried it, it work nearly fine except that the rounding gives : 0.999 and not 1.000 for instance.
And the shape stay off grid
Laurent
I tried it, it work nearly fine except that the rounding gives : 0.999 and not 1.000 for instance.
And the shape stay off grid
I tried scle_and_snap : it work very well ! But all path are turned to polygons and all arrays are flattened, so the GDS becomes huge !
It is OK at the end of the layout before tape-out, but not to transfer a design from a technology to another.
Laurent
For other readers here is the code for scale_and_snap Laurent refers to. It's based on the
Layout#scale_and_snap
function:The processing will explode instance arrays as it needs to analyse each instantiation separately. I think this does not happen when the array repetition vector is already on-grid, but I may be wrong.
And paths can't be corner-snapped in general - just snapping the spine would not necessarily produce an on-grid hull contour. Hence the conversion to polygons.
And Laurent's reply is valid: this script is not something to use during layout but for layout cleaning before tapeout.
Matthias
I have run into trouble using paths relating to the non-grid
vertices of the "hull". I have moved to a style where I build
polygon "paths" out of ortho and diagonal on-grid "sticks"
and merge them.
I think that a cool feature could be a "partial" feature-group
addition, "nudge selected vertices to grid". Of course the
devil is in the details - what to give up, to get grid-aligned;
are you going to let path width shrink below the property
value, if so how / where? Probably entails making the path
into a poly right off.
I've done some of this too by hand, but it gets messy as you
have to dial the snap-grid down to the DBU in some cases,
then hand drag it to the grid point (otherwise you'll move -by-
a grid-step, not -to- a grid-step).
Maybe there's a way, though?
Snap to grid is a good suggestion, could be used for partial mode too.
Snapping of paths is kind of difficult. In the general case I'd say snapping should be applied to the vertices. If path width is a multiple of twice the grid and the extensions are multiples of the grid too then the hull points would usually be on-grid too. Except if the path has any-angle segments: in this case the corners will almost always be off-grid.
Matthias