I recently created my first CIF file using KLayout.
I use this file on a Microtech Laserwriter, that needs to import the CIF and convert it to its native LDF format.
When I tried to do this it reported an error and the conversion failed.
Going on a hunch, I loaded the file CleWin, perfomed no changes on the file, saved it again as a CIF - and magiacally the conversion to LDF worked perfectly!
Any ideas on how I can prevent this problem to begin with?
What could be the difference between how KLayout saves its CIF files and CleWin, while CleWin can still load perfectly the KLayout CIF?!
Comments
Hello,
difficult to tell. Is there any message giving details about the problem?
Basically there are different flavours of CIF. For example, Klayout uses 9x records to specify cell names and path types. Maybe the LDF converter does not accept them.
CIF is just text, so you could try to change the file and figure out what is the cause of the problem.
Since CleWin accepts Klayout's CIF, I don't see that it's basically wrong. Without further details and lacking knowledge about or access to the LDF converter, I cannot assist in solving that issue however.
Matthias
I have solved the problem. There are two possible reasons for failure - one is incorrect units (the machine does not expect them), and commas between X Y pairs. So the model must be created with units of 0.001 micron, for it to be usable on the Microtech laser writer. I have created the following script to make sure all of other features of the CIF are compatible.
# $description: Save CIF for LW
# $show-in-menu
#Script to save and hopefully process saved file so that laser writer software is happy
#empty is string directs to current directory
file_name=RBA::FileDialog.ask_save_file_name("Save CIF File for LaserWriter","","CIF (*.cif)")
slo=RBA::SaveLayoutOptions.new
#need to set up for for cif file and correct units
slo.format="CIF"
mw = RBA::Application::instance.main_window
#method to save file
currentLayout=RBA::LayoutView::current
begin
currentLayout.save_as(mw.current_view_index,file_name,slo)
rescue
else
units=RBA::CellView::active.layout.dbu
#I just noticed the CleWin file was saved with units of 0.001, and this is not true for y
#original KLayout. This might be another compatibility issue
#Also the DS commands (definition start) have different scaling factors
cifText=[nil] #otherwise there is a problem that it is only local to block
cifFile=File.open(file_name,'r') do |file|
#This is not neccesary but makes sure file will be closed
cifText=File.readlines(file_name)
end
#cifText=cifText.drop(0)
File.open(file_name,'w') do |file|
cifText[0] = "(CIF written by CleWin 4.1);\n(1 unit = #{units} micron);\n(Center for Nanoscience and);
(Nanotechnology);\n(The Hebrew University of Jerusalem);\n(Jerusalem, Israel);\n(Layer names:);\n"
cifText[1]="DS1 1 10;" #not clear if this matters but definitly depends on choice of units
cifText[-1]="C 1;"
cifText<<"E"
cifText.each {|i| file.puts((i).gsub(","," "))}
end
end
Hi,
very good, thanks! I'm glad to see people utilize the available features to solve their problems :-)
I am not really familiar with CIF. I regarded CIF a somewhat outdated format with a couple of flaws so far and your experiences don't really make me confident.
All I have is the public spec (http://en.wikipedia.org/wiki/Caltech_Intermediate_Form). I try to comply with that one as far as possible, but there appear to be some variants out there.
Is there any alternative spec I could use as a basis for the implementation? Of course it should be possible to accept comma instead of blanks to, but I'd like to know what else to expect. And maybe there are places where a comma is part of a name, label text or similar.
Regards,
Matthias
It is KLayout that is saving with commas, not CleWin. The macro I wrote removes the commas.
If you look at the wiki page there are no commas there as well.
Also, I add the "C 1" line at the end, but I'm not sure what it does.
In any event, it loads correctly on the laser writer.
Regards,
Simcha
Hi Simcha,
it's even more weired: according to the spec, the separator can be ANY character except semicolon, brackets and a few others ... I see I misunderstood the spec so far. It's even possible to use verbose commands such as "Cell" instead of "C" since lower-case characters are ignored and count as "blanks". I'll try to extend the CIF reader so it complies with the spec. But commas are definitely allowed as separators. In fact all test cases I got so far use comma separators.
Something for the next release.
Thanks and regards,
Matthias
I think if you just add an option for choosing the separator character when saving it should solve many compatibility problems.
You are doing a real service for science, as the equivalent commercial software we use costs 30K for a single license and all the other open source options I saw were inferior to your program.
Thanks and Regards,
Simcha
I discovered some more problems with the CIF format.
The file saved does not call any of the statements declared.
After the last "DF" command, the highest level statements should be called, but instead only a "E" command is issued.
I fixed this in my script by inserting this manually, but this only works for a flattened structure.
Any chance these problems will be fixed for the next release?
Regards,
Simcha
simchak,
Are you able to paste in a simple CIF file, one saved as-is from KL without these "highest level statements" called, and one manually fixed? (Or, one made in a different tool if you prefer?
I am talking of a non-flattened file, as you mention it works for a flattened file. Just something simple like some rectangles.
I have some familiarity with CIF. Before I discovered KLayout I wrote a bunch of Matlab code to generate CIF files based on parametric input. I'm glad those days are over.. KL is much better to code in!
Thanks,
David
Hi Simcha,
Are you sure?
My understanding is that the highest level is a unnamed entity and there is no equivalent in GDS, so there is no way to populate that space. In GDS, everything is inside cells and cells do not need to be called. So basically there can be multiple top cells. How will this be mapped to CIF? And how can be the CIF reader convert that back to a GDS-like layout space?
I had a look at some samples - for example the CIF files provided for the MOSIS library (https://www.mosis.com/pages/design/flows/design-flow-scmos-kits). They pretty much look the same than my CIF files - they also list a couple of structures in the DS ... DF form and end with an E after the final DF.
Matthias
Yes, I am sure. I generated the file with a commercial product and compared.
If you want to have multiple top level cells the CIF file will simply call each one individually (before the E command).
If you are saving as GDS you simply create a cell that references those top level cells.
I'd show you the files (to make sure, I have the file generated from my script and the one generated from the commercial program), but this forum doesn't have attachments.
CIF files are simple text files, you can paste a short example here. If you precede each line with four space characters then it will show up in code markdown format. To put four spaces in front of each line just select all and indent it with a text editor like Notepad++.
If you must send the actual file you can email it to Matthias, but better to paste it here for benefit of future readers.
David
is it possible those files are structured that way because they are component libraries and not actual layouts?
David - thanks!
Following is the last couple of lines for CleWin generated file:
9 TOP;
(CleArray 3 2 2 100000 100000 12060000 100000 100000 12060000 0 1072693248 0 0);
C 5 T100000 100000;
(CleArray 2 10 50 100000 600000 1100000 600000 100000 5600000 0 1072693248 0 0);
C 7 T100000 600000;
C 1 T0 0;
L L1;
P 2700000 5800000 3100000 6200000 3500000 5800000;
B 100000 6200000 -50000 3100000;
B 100000 6200000 6250000 3100000;
B 6400000 100000 3100000 -50000;
B 6400000 100000 3100000 6250000;
DF;
C 4;
E
So you see, it calls the top level statement before ending, and this is what works with laser-writer software.
slo=RBA::SaveLayoutOptions.new
slo.format="CIF"
mw = RBA::Application::instance.main_window
#method to save file
currentLayout=RBA::LayoutView::current
file_name=RBA::FileDialog.ask_save_file_name("Save CIF File for LaserWriter","","CIF (*.cif)")
if file_name
currentLayout.save_as(mw.current_view_index,file_name,slo)
units=RBA::CellView::active.layout.dbu
cifText=[nil] #otherwise there is a problem that it is only local to block
cifFile=File.open(file_name,'r') do |file|
cifText=File.readlines(file_name)
end
topLine=cifText.find_index("9 TOP;\n")
cifTextC=cifText[(topLine-1)].gsub("DS","C")
cifTextC=cifTextC.gsub(" 1 10;",";")
#Need to make sure we call top cell
File.open(file_name,'w') do |file|
cifText[-1]=cifTextC
cifText<< "E"
cifText.each {|i| file.puts((i).gsub(","," "))}
end
end
Last lines:
C 25 T 0 0;
DF;
C 80;
E
Hi all,
to wrap that up:
Is this correct?
Matthias
Well, that is already the case. I'm just concerned that writing and re-reading will modify the layout since the top level is added to the original cells. From my point of view, a write/read round trip should leave a layout the same as far as possible.
I'll make the dummy calls a writer option, so everybody can configure what is best for the specific application. I'll also add an option that uses blanks instead in of comma characters for x/y value pairs.
Matthias