├── .gitignore ├── ARCHITECTURE.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── cells ├── LC_oscillator │ ├── cdac.lua │ ├── connector.lua │ ├── core.lua │ ├── cross_coupled_pair.lua │ ├── current_mirror.lua │ ├── fill.lua │ ├── fixed_capacitor.lua │ ├── resonator.lua │ ├── toplevel.lua │ ├── varactorbase.lua │ └── varbank.lua ├── RF │ ├── patterned_ground_shield.lua │ └── transmission_line.lua ├── SAR_ADC │ ├── buf_array.lua │ ├── cap_array.lua │ ├── sample_and_hold.lua │ ├── switch_network_down.lua │ └── switch_network_up.lua ├── __test │ ├── align_sub.lua │ ├── align_top.lua │ ├── angled_path.lua │ ├── path.lua │ ├── pathextension.lua │ ├── premapped.lua │ ├── rectangle.lua │ ├── rotation.lua │ ├── sub.lua │ ├── subsub.lua │ ├── top.lua │ ├── translation.lua │ └── via.lua ├── analog │ ├── LC_oscillator.lua │ ├── common_centroid.lua │ ├── cross_coupled_pair.lua │ ├── crystal_IC_oscillator.lua │ ├── current_mirror_multiple.lua │ ├── current_starved_ringoscillator.lua │ ├── currentmirror.lua │ ├── inverter.lua │ ├── inverter_chain.lua │ ├── ringoscillator.lua │ ├── self_biased_inverter.lua │ ├── simple_currentmirror.lua │ ├── stacked_ringoscillator.lua │ ├── strongARM_comparator.lua │ ├── track_hold.lua │ ├── transmission_gate.lua │ └── vertical_inverter.lua ├── auxiliary │ ├── decap.lua │ ├── groundmesh.lua │ ├── guardring.lua │ ├── metalgrid.lua │ ├── pad.lua │ ├── padring.lua │ ├── pads.lua │ ├── powergridadapter.lua │ ├── svg2layout.lua │ ├── text.lua │ └── welltap.lua ├── basic │ ├── cmos.lua │ ├── cmos_bjt.lua │ ├── cmos_connected.lua │ ├── diode.lua │ ├── ldmos.lua │ ├── mosfet.lua │ ├── polyresistor.lua │ └── stacked_mosfet_array.lua ├── logic │ └── counter.lua ├── optical │ └── grated_coupler.lua ├── passive │ ├── capacitor │ │ ├── mom.lua │ │ └── tin.lua │ └── inductor │ │ ├── circular.lua │ │ ├── octagonal.lua │ │ ├── spiral.lua │ │ └── spiral_rectangular.lua ├── pll │ ├── c2mos_frequency_divider.lua │ └── pfd.lua ├── stdcells │ ├── 1_inv_gate.lua │ ├── 21_gate.lua │ ├── 221_gate.lua │ ├── 22_gate.lua │ ├── all_cells.lua │ ├── and_gate.lua │ ├── base.lua │ ├── buf.lua │ ├── cinv.lua │ ├── colstop.lua │ ├── dff.lua │ ├── dffnq.lua │ ├── dffnrq.lua │ ├── dffnrsq.lua │ ├── dffnsq.lua │ ├── dffpq.lua │ ├── dffprq.lua │ ├── dffprsq.lua │ ├── dffpsq.lua │ ├── endcell.lua │ ├── fill.lua │ ├── generic2bit.lua │ ├── half_adder.lua │ ├── harness.lua │ ├── isogate.lua │ ├── latch.lua │ ├── leftcolstop.lua │ ├── mux.lua │ ├── nand_gate.lua │ ├── nand_nor_layout_base.lua │ ├── nor_gate.lua │ ├── not_gate.lua │ ├── or_gate.lua │ ├── rightcolstop.lua │ ├── rowstop.lua │ ├── tbuf.lua │ ├── tgate.lua │ ├── tie_high.lua │ ├── tie_highlow.lua │ ├── tie_low.lua │ ├── xnor_gate.lua │ └── xor_gate.lua └── transmitter │ └── memory.lua ├── configure.sh ├── doc ├── Makefile ├── celldesign.pdf ├── doc.tex ├── export.pdf ├── info │ ├── mosfet.png │ ├── mosfet_complex.png │ └── ringoscillator.png ├── presentation.pdf ├── src │ ├── Makefile │ ├── celldesign │ │ ├── Makefile │ │ ├── code │ │ │ ├── hierarchy_example.lua │ │ │ ├── merge_into_example.lua │ │ │ ├── momcap.lua │ │ │ ├── ringoscillator.lua │ │ │ ├── ringoscillator_anchor.lua │ │ │ ├── ringoscillator_move_point.lua │ │ │ ├── ringoscillator_nocopy.lua │ │ │ └── simple_rectangle.lua │ │ └── main.tex │ ├── export │ │ ├── Makefile │ │ └── main.tex │ ├── preamble.tex │ ├── presentation │ │ ├── Makefile │ │ ├── beamerthemeopc.sty │ │ ├── main.auxlock │ │ ├── main.snm │ │ ├── main.tex │ │ └── preamble.tex │ ├── techdoc │ │ ├── Makefile │ │ └── main.tex │ ├── techfiles │ │ ├── Makefile │ │ └── main.tex │ └── userguide │ │ ├── Makefile │ │ └── main.tex ├── techdoc.pdf ├── techfiles.pdf └── userguide.pdf ├── examples ├── autofill │ ├── main.lua │ └── run.sh ├── cells │ ├── LC_oscillator.lua │ ├── comparator.lua │ ├── current_starved_ringoscillator.lua │ ├── mosfet.lua │ ├── ringoscillator.lua │ └── run.sh ├── digital │ ├── generate.lua │ └── run.sh ├── place_and_route_automatic │ ├── cellinfo.lua │ ├── generate_cell.lua │ ├── place_route_generate.lua │ ├── run.sh │ └── serial_ctrl.v └── svg │ ├── gilfoyle.lua │ ├── gilfoyle.svg │ ├── pineapple.lua │ ├── pineapple.svg │ ├── run.sh │ ├── talentandsweat.lua │ └── talentandsweat.svg ├── export ├── debug │ └── init.lua ├── gdstext │ └── init.lua ├── html │ └── init.lua ├── luaSKILL │ └── init.lua ├── magic │ └── init.lua ├── oasis │ └── init.lua ├── ppm │ └── init.lua ├── svg │ └── init.lua ├── template │ └── init.lua └── tikz │ └── init.lua ├── interface └── virtuoso │ ├── backup.il │ ├── call.il │ ├── cdsinit.il.sample │ ├── cells.il │ ├── edit_update.il │ ├── export.il │ ├── init.il │ ├── menu.il │ ├── misc.il │ ├── settings.il │ └── subcell.il ├── logo ├── Makefile ├── logo.pdf ├── logo.tex └── logo.txt ├── resources ├── extract_pinoffsets.lua ├── extract_stdcells_netlists.sh ├── opc.lib ├── opc.lylvs ├── opc.lyp ├── opc.v └── stdcells_netlists │ ├── 1_inv_gate.sp │ ├── 21_gate.sp │ ├── 221_gate.sp │ ├── 22_gate.sp │ ├── all_cells.sp │ ├── and_gate.sp │ ├── buf.sp │ ├── cinv.sp │ ├── colstop.sp │ ├── dff.sp │ ├── dffnq.sp │ ├── dffnrq.sp │ ├── dffnsq.sp │ ├── dffpq.sp │ ├── dffprq.sp │ ├── dffpsq.sp │ ├── endcell.sp │ ├── generic2bit.sp │ ├── half_adder.sp │ ├── harness.sp │ ├── isogate.sp │ ├── latch.sp │ ├── latch_cell.sp │ ├── leftcolstop.sp │ ├── mux.sp │ ├── nand_gate.sp │ ├── nand_nor_layout_base.sp │ ├── nor_gate.sp │ ├── not_gate.sp │ ├── or_gate.sp │ ├── register.sp │ ├── rightcolstop.sp │ ├── shiftregister.sp │ ├── tbuf.sp │ ├── test.sp │ ├── tgate.sp │ ├── xnor_gate.sp │ └── xor_gate.sp ├── saradc ├── DAC_differential.lua ├── caparray.lua ├── comparator.lua ├── sample_and_hold.lua ├── switch_network_down.lua └── switch_network_up.lua ├── src ├── Makefile ├── bltrshape.c ├── bltrshape.h ├── cells.c ├── cells.h ├── cells │ └── powergrid.c ├── cmdoptions.c ├── cmdoptions.h ├── cmdoptions_def.c ├── cpu.c ├── cpu.h ├── create_latex_API_doc.c ├── embed_compiled_lua_file.c ├── export.c ├── export.h ├── export_common.c ├── export_common.h ├── export_writer.c ├── export_writer.h ├── filesystem.c ├── filesystem.h ├── gdsexport.c ├── gdsexport.h ├── gdsparser.c ├── gdsparser.h ├── generate_manpage.c ├── geometry.c ├── geometry.h ├── geometry_triangulate.c ├── graphics.c ├── graphics.h ├── hashmap.c ├── hashmap.h ├── info.c ├── info.h ├── lcheck.c ├── lcheck.h ├── ldebug.c ├── ldebug.h ├── ldir.c ├── ldir.h ├── lgenerics.c ├── lgenerics.h ├── lgeometry.c ├── lgeometry.h ├── lobject.c ├── lobject.h ├── lplacement.c ├── lplacement.h ├── lplacer.c ├── lplacer.h ├── lplacer_classic.c ├── lplacer_classic.h ├── lplacer_common.c ├── lplacer_common.h ├── lplacer_floorplan.h ├── lplacer_nonoverlapping.c ├── lplacer_nonoverlapping.h ├── lplacer_rand.c ├── lplacer_rand.h ├── lpoint.c ├── lpoint.h ├── lpostprocess.c ├── lpostprocess.h ├── lrouter.c ├── lrouter.h ├── lrouter_field.c ├── lrouter_field.h ├── lrouter_min_heap.c ├── lrouter_min_heap.h ├── lrouter_moves.c ├── lrouter_moves.h ├── lrouter_net.c ├── lrouter_net.h ├── lrouter_queue.c ├── lrouter_queue.h ├── lrouter_route.c ├── lrouter_route.h ├── lua │ ├── lapi.c │ ├── lapi.h │ ├── lauxlib.c │ ├── lauxlib.h │ ├── lbaselib.c │ ├── lcode.c │ ├── lcode.h │ ├── lcorolib.c │ ├── lctype.c │ ├── lctype.h │ ├── ldblib.c │ ├── ldebug.c │ ├── ldebug.h │ ├── ldo.c │ ├── ldo.h │ ├── ldump.c │ ├── lfunc.c │ ├── lfunc.h │ ├── lgc.c │ ├── lgc.h │ ├── linit.c │ ├── liolib.c │ ├── ljumptab.h │ ├── llex.c │ ├── llex.h │ ├── llimits.h │ ├── lmathlib.c │ ├── lmem.c │ ├── lmem.h │ ├── loadlib.c │ ├── lobject.c │ ├── lobject.h │ ├── lopcodes.c │ ├── lopcodes.h │ ├── lopnames.h │ ├── loslib.c │ ├── lparser.c │ ├── lparser.h │ ├── lprefix.h │ ├── lstate.c │ ├── lstate.h │ ├── lstring.c │ ├── lstring.h │ ├── lstrlib.c │ ├── ltable.c │ ├── ltable.h │ ├── ltablib.c │ ├── ltm.c │ ├── ltm.h │ ├── lua.h │ ├── lua.hpp │ ├── luac.c │ ├── luaconf.h │ ├── lualib.h │ ├── lundump.c │ ├── lundump.h │ ├── lvm.c │ ├── lvm.h │ ├── lzio.c │ └── lzio.h ├── lua_util.c ├── lua_util.h ├── lutil.c ├── lutil.h ├── main.api_help.c ├── main.api_help.h ├── main.api_help │ ├── aux.c │ ├── curve.c │ ├── generics.c │ ├── geometry.c │ ├── global.c │ ├── graphics.c │ ├── layouthelpers.c │ ├── object.c │ ├── pcell.c │ ├── placement.c │ ├── placer.c │ ├── point.c │ ├── router.c │ ├── routing.c │ ├── technology.c │ └── util.c ├── main.c ├── main.cell.c ├── main.cell.h ├── main.functions.c ├── main.functions.h ├── main.gds.c ├── main.gds.h ├── main.tutorial.c ├── main.tutorial.h ├── main.verilog.c ├── main.verilog.h ├── math.h ├── modules │ ├── aux.lua │ ├── check.lua │ ├── generator.lua │ ├── globals.lua │ ├── graphics.lua │ ├── layouthelpers.lua │ ├── load.lua │ ├── pcell.lua │ ├── placement.lua │ ├── routing.lua │ ├── stack.lua │ ├── util.lua │ ├── verilog.lua │ └── verilogprocessor.lua ├── object.c ├── object.h ├── pcell.c ├── pcell.h ├── placement.c ├── placement.h ├── point.c ├── point.h ├── polygon.c ├── polygon.h ├── postprocess.c ├── postprocess.h ├── scripts │ ├── assistant.lua │ ├── list_anchors.lua │ ├── list_cells.lua │ ├── list_parameters.lua │ └── templates.lua ├── shape.c ├── shape.h ├── skillexport.c ├── skillexport.h ├── support │ └── gdstypetable.lua ├── tagged_value.c ├── tagged_value.h ├── technology.c ├── technology.h ├── terminal_colors.c ├── terminal_colors.h ├── transformationmatrix.c ├── transformationmatrix.h ├── union.c ├── union.h ├── util.c ├── util.h ├── util_cmodule.c ├── util_cmodule.h ├── vector.c ├── vector.h └── version.h └── tech ├── freePDK45 ├── config.lua ├── constraints.lua ├── layermap.lua └── vias.lua ├── opc ├── config.lua ├── constraints.lua ├── layermap.lua ├── place_route │ └── cellinfo.lua └── vias.lua ├── skywater130 ├── config.lua ├── constraints.lua ├── layermap.lua └── vias.lua └── template ├── config.lua └── layermap.lua /.gitignore: -------------------------------------------------------------------------------- 1 | # main programs and generated code files 2 | Makefile 3 | opc 4 | opc-debug 5 | !tech/opc 6 | src/embed_compiled_lua_file 7 | src/create_latex_API_doc 8 | src/config.h 9 | src/modulemanager.c 10 | src/modulemanager.h 11 | src/scriptmanager.c 12 | src/scriptmanager.h 13 | src/generate_manpage 14 | src/tags 15 | src/debug 16 | src/release 17 | opc.1 18 | 19 | # generated layouts and helpers 20 | openPCells.* 21 | pineapple.gds 22 | talentandsweat.gds 23 | gilfoyle.gds 24 | openPCells_extracted.cir 25 | pfile.lua 26 | verilogimport 27 | 28 | # generated files in example folder 29 | examples/digital/digital.lua 30 | examples/*/*.gds 31 | examples/*/*.sp 32 | 33 | # NDA-related 34 | tech/GF22FDSOI 35 | tech/cmos22fdsoi 36 | tech/TSMC28HPCplus 37 | 38 | # build object files 39 | src/*.o 40 | 41 | # code tags 42 | tags 43 | 44 | # lua object files 45 | src/lua/lua 46 | src/lua/luac 47 | src/lua/*.o 48 | src/lua/liblua.a 49 | 50 | # tex auxiliary files 51 | *.aux 52 | *.log 53 | *.toc 54 | *.pygtex 55 | *_minted* 56 | *.nav 57 | *.out 58 | *.vrb 59 | 60 | # development information 61 | devinfo 62 | 63 | # test code 64 | srctodo 65 | 66 | # test files 67 | testfiles 68 | debug 69 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | Hello and thanks for considering contributing to openPCells. This project is intended to be used and enhanced by many people, gathering different kinds of 3 | knowledge. 4 | 5 | ## How do I contribute? 6 | All kinds of contributions are welcome, including (but not limited to) feature requests, bug fixes, cell defintions, documentation enhancements and technology 7 | definitions. Furthermore, the provided cells are currently not being tested in many technologies, as this needs access to those. If you are working with 8 | integrated circuits and have technology access, testing the generated layouts of various cells with different parameter values is very valuable for improving the 9 | code of the cells. 10 | 11 | I try to add stuff that needs fixing or implementing to the todo file. There is of course also the issue list on github, but that's probably out-of-sync. 12 | -------------------------------------------------------------------------------- /cells/LC_oscillator/fill.lua: -------------------------------------------------------------------------------- 1 | function layout(cell, _P, env) 2 | local filler = pcell.create_layout("auxiliary/decap", "_filler", { 3 | cellsize = env.decap.cellsize, 4 | meshmetals = { 8 }, 5 | meshmetalwidths = { 1250 }, 6 | drawgrid = false, 7 | drawmoscap = false, 8 | }) 9 | --cell:merge_into(filler:copy():move_to(point.create(-60000, -15000))) 10 | --cell:merge_into(filler:copy():move_to(point.create(-60000, -25000))) 11 | end 12 | -------------------------------------------------------------------------------- /cells/RF/patterned_ground_shield.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | pcell.add_parameters( 3 | { "width", 100 }, 4 | { "space", 100 }, 5 | { "regionwidth", 10000 } 6 | ) 7 | end 8 | 9 | function layout(shield, _P) 10 | local pitch = _P.width + _P.space 11 | local numlines = _P.regionwidth // (2 * pitch) 12 | 13 | -- assemble quarter layout 14 | local quarter = object.create("quarter") 15 | for i = 1, numlines do 16 | geometry.rectanglebltr(quarter, generics.metal(3), 17 | point.create(-numlines * pitch + _P.space / 2 + (i - 1) * pitch, -numlines * pitch), 18 | point.create(-numlines * pitch + _P.space / 2 + (i - 1) * pitch + _P.width, -numlines * pitch + (i - 1) * pitch + _P.width + _P.space / 2) 19 | ) 20 | end 21 | 22 | -- assemble half layout 23 | local half = object.create("half") 24 | half:merge_into(quarter) 25 | half:merge_into(quarter:mirror_at_yaxis()) 26 | 27 | -- assemble full layout 28 | shield:merge_into(half) 29 | shield:merge_into(half:rotate_90_left()) 30 | shield:merge_into(half:rotate_90_left()) 31 | shield:merge_into(half:rotate_90_left()) 32 | end 33 | -------------------------------------------------------------------------------- /cells/RF/transmission_line.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | pcell.add_parameters( 3 | { "width", 5000 }, 4 | { "length", 50000 }, 5 | { "groundwidth", 10000 }, 6 | { "groundspace", 5000 }, 7 | { "shieldwidth", 100 }, 8 | { "shieldspace", 100 }, 9 | { "metalnum", -1 }, 10 | { "shieldmetal", 1 } 11 | ) 12 | end 13 | 14 | function layout(tline, _P) 15 | geometry.rectangle(tline, generics.metal(_P.metalnum), _P.length, _P.width) 16 | geometry.rectangle(tline, generics.metal(_P.metalnum), _P.length, _P.groundwidth, 0, 0, 1, 2, 0, _P.width + 2 * _P.groundspace + _P.groundwidth) 17 | geometry.rectangle(tline, generics.metal(_P.shieldmetal), _P.shieldwidth, _P.width + 2 * _P.groundspace + 2 * _P.groundwidth, 0, 0, _P.length // (_P.shieldwidth + _P.shieldspace), 1, _P.shieldwidth + _P.shieldspace, 0) 18 | geometry.via(tline, _P.shieldmetal, _P.metalnum, _P.length, _P.groundwidth, 0, 0, 1, 2, 0, _P.width + 2 * _P.groundwidth) 19 | tline:add_port("P1", generics.metalport(_P.metalnum), point.create(-_P.length / 2, 0)) 20 | tline:add_port("PG1", generics.metalport(_P.metalnum), point.create(-_P.length / 2, _P.width / 2 + _P.groundspace + _P.groundwidth / 2)) 21 | tline:add_port("PG1", generics.metalport(_P.metalnum), point.create(-_P.length / 2, -_P.width / 2 - _P.groundspace - _P.groundwidth / 2)) 22 | tline:add_port("P2", generics.metalport(_P.metalnum), point.create( _P.length / 2, 0)) 23 | tline:add_port("PG2", generics.metalport(_P.metalnum), point.create( _P.length / 2, _P.width / 2 + _P.groundspace + _P.groundwidth / 2)) 24 | tline:add_port("PG2", generics.metalport(_P.metalnum), point.create( _P.length / 2, -_P.width / 2 - _P.groundspace - _P.groundwidth / 2)) 25 | end 26 | -------------------------------------------------------------------------------- /cells/__test/align_sub.lua: -------------------------------------------------------------------------------- 1 | function layout(cell) 2 | geometry.ring(cell, generics.metal(1), point.create(0, 0), 1000, 1000, 100) 3 | cell:set_alignment_box( 4 | point.create(-500, -500), 5 | point.create(500, 500), 6 | point.create(-400, -400), 7 | point.create(400, 400) 8 | ) 9 | end 10 | -------------------------------------------------------------------------------- /cells/__test/align_top.lua: -------------------------------------------------------------------------------- 1 | function layout(cell) 2 | local subref = pcell.create_layout("__test/align_sub", "sub") 3 | local subcenter = cell:add_child(subref, "sub1") 4 | subcenter:translate(2000, 2000) 5 | local subtop = cell:add_child(subref, "subtop") 6 | subtop:abut_top(subcenter) 7 | subtop:align_left(subcenter) 8 | local subbottom = cell:add_child(subref, "subbottom") 9 | subbottom:abut_bottom(subcenter) 10 | subbottom:align_left(subcenter) 11 | local subleft = cell:add_child(subref, "subleft") 12 | subleft:abut_left(subcenter) 13 | subleft:align_bottom(subcenter) 14 | local subright = cell:add_child(subref, "subright") 15 | subright:abut_right(subcenter) 16 | subright:align_bottom(subcenter) 17 | end 18 | -------------------------------------------------------------------------------- /cells/__test/angled_path.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | 3 | end 4 | 5 | function layout(cell) 6 | geometry.any_angle_path(cell, generics.metal(1), { 7 | point.create(0, 0), 8 | point.create(10000, 100000), 9 | point.create(15000, 100000), 10 | }, 5000, 100, true, true) 11 | end 12 | -------------------------------------------------------------------------------- /cells/__test/path.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | 3 | end 4 | 5 | function layout(cell) 6 | geometry.path(cell, generics.metal(1), { point.create(-100, 0), point.create(100, 0) }, 20) 7 | end 8 | -------------------------------------------------------------------------------- /cells/__test/pathextension.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | 3 | end 4 | 5 | function layout(cell, _P) 6 | geometry.path(cell, generics.metal(1), { point.create(0, 0), point.create(1000, 0) }, 100, "square") 7 | end 8 | -------------------------------------------------------------------------------- /cells/__test/premapped.lua: -------------------------------------------------------------------------------- 1 | function layout(cell) 2 | geometry.rectangle(cell, generics.premapped(nil, { gds = { layer = 0, purpose = 0 }, SKILL = { layer = "M1", purpose = "drawing" } }), 100, 100) 3 | end 4 | -------------------------------------------------------------------------------- /cells/__test/rectangle.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | end 3 | 4 | function layout(cell, _P) 5 | geometry.rectangle(cell, generics.metal(1), 50, 50, 0, 50) 6 | --geometry.rectangle(cell, generics.metal(1), 50, 50):translate(0, -50) 7 | --cell:add_anchor("A", point.create(0, 75)) 8 | end 9 | -------------------------------------------------------------------------------- /cells/__test/rotation.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | 3 | end 4 | 5 | function layout(cell) 6 | local subref = object.create("subref") 7 | geometry.rectanglebltr(subref, generics.metal(1), point.create(0, 0), point.create(100, 100)) 8 | local sub = cell:add_child(subref, "sub") 9 | sub:rotate_90_left() 10 | end 11 | -------------------------------------------------------------------------------- /cells/__test/sub.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | 3 | end 4 | 5 | function layout(cell, _P) 6 | local subsub = pcell.create_layout("__test/subsub", "subsub") 7 | cell:add_child(subsub, "subsub0"):translate(-100, -100) 8 | cell:add_child(subsub, "subsub1"):translate( 100, -100) 9 | cell:add_child(subsub, "subsub2"):translate( 0, 100) 10 | 11 | geometry.rectangle(cell, generics.metal(1), 20, 20) 12 | end 13 | -------------------------------------------------------------------------------- /cells/__test/subsub.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | 3 | end 4 | 5 | function layout(cell, _P) 6 | geometry.via(cell, 1, 2, 100, 100) 7 | end 8 | -------------------------------------------------------------------------------- /cells/__test/top.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | 3 | end 4 | 5 | function layout(cell, _P) 6 | -- place flat rectangle 7 | --geometry.rectangle(cell, generics.metal(1), 200, 200) 8 | 9 | -- place subcells 10 | local sub = pcell.create_layout("__test/sub", "sub") 11 | cell:add_child(sub, "sub0"):translate( 0, 500) 12 | cell:add_child(sub, "sub2"):translate( 0, -500):flipy() 13 | cell:add_child(sub, "sub3"):translate( 500, 0) 14 | cell:add_child(sub, "sub4"):translate(-500, 0) 15 | end 16 | -------------------------------------------------------------------------------- /cells/__test/translation.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | end 3 | 4 | function layout(cell, _P) 5 | geometry.rectangle(cell, generics.metal(1), 50, 50) 6 | cell:translate(200, 0) 7 | geometry.rectangle(cell, generics.metal(2), 50, 50) 8 | end 9 | -------------------------------------------------------------------------------- /cells/__test/via.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | 3 | end 4 | 5 | function layout(cell) 6 | geometry.via(cell, 1, 2, 80, 60) 7 | end 8 | -------------------------------------------------------------------------------- /cells/analog/LC_oscillator.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | 3 | end 4 | 5 | function layout(osc, _P) 6 | local inductor = pcell.create_layout("passive/inductor/octagonal", "inductor", { turns = 1, metalnum = -2 }) 7 | osc:merge_into(inductor) 8 | 9 | local cap = pcell.create_layout("passive/capacitor/mom", "momcap", { fingers = 20, fheight = 2000, firstmetal = 3, lastmetal = 5 }) 10 | osc:merge_into(cap:translate(0, -20000)) 11 | 12 | local ccp = pcell.create_layout("analog/cross_coupled_pair", "cross_coupled_pair") 13 | osc:merge_into(ccp) 14 | end 15 | -------------------------------------------------------------------------------- /cells/analog/crystal_IC_oscillator.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | pcell.add_parameters( 3 | { "invfingers", 4 }, 4 | { "resfingers", 50 } 5 | ) 6 | end 7 | 8 | function layout(oscillator, _P) 9 | local gatecontacts = util.fill_all_with(_P.invfingers, "center") 10 | local npcontacts = util.fill_even_with(_P.invfingers + 1, "inner", "power") 11 | local cmosref = pcell.create_layout("basic/cmos", "mosfets", { 12 | gatelength = 40, 13 | gatespace = 90, 14 | gatecontactpos = gatecontacts, 15 | pcontactpos = npcontacts, 16 | ncontactpos = npcontacts, 17 | separation = 400, 18 | }) 19 | 20 | local resref = pcell.create_layout("basic/polyresistor", "resistor", { nxfingers = _P.resfingers, nyfingers = 2, dummies = 0, xspace = 90, contactheight = 200, extension = 300 }) 21 | 22 | local moscore = oscillator:add_child(cmosref, "moscore") 23 | local polyres = oscillator:add_child(resref, "resistor") 24 | end 25 | -------------------------------------------------------------------------------- /cells/analog/currentmirror.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | pcell.add_parameters( 3 | { "ifingers", 4 }, 4 | { "ofingers", 4 }, 5 | { "interdigitate", false } 6 | --{ "sourcemetal", 2 }, 7 | --{ "outmetal", 3 } 8 | ) 9 | end 10 | 11 | function layout(currentmirror, _P) 12 | local baseopt = { 13 | fingerwidth = 500, 14 | connectsource = true, 15 | connsourcewidth = 200, 16 | connsourcespace = 100, 17 | drawtopgate = true, 18 | drawtopgatestrap = true, 19 | topgatecompsd = false, 20 | }) 21 | local diode = pcell.create_layout("basic/mosfet", "diode", util.add_options(baseopt, { 22 | fingers = _P.ifingers, 23 | diodeconnected = true, 24 | })) 25 | local source = pcell.create_layout("basic/mosfet", "source", util.add_options(baseopt, { 26 | fingers = _P.ofingers, 27 | conndrainmetal = 2, 28 | drawdrainvia = true, 29 | connectdrain = true, 30 | })) 31 | diode:move_anchor("sourcedrainrightbl") 32 | source:move_anchor("sourcedrainleftbl") 33 | currentmirror:merge_into(diode) 34 | currentmirror:merge_into(source) 35 | 36 | geometry.rectanglebltr(currentmirror, generics.metal(1), diode:get_anchor("topgate1bl"), source:get_anchor(string.format("topgate%dtr", _P.ofingers))) 37 | end 38 | -------------------------------------------------------------------------------- /cells/analog/track_hold.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | 3 | end 4 | 5 | function layout(cell, _P) 6 | local momcap = pcell.create_layout("passive/capacitor/mom", "momcap") 7 | local mom1 = cell:add_child(momcap, "mom2") 8 | mom1:move_anchor("minus") 9 | local mom2 = cell:add_child(momcap, "mom2") 10 | mom2:move_anchor("plus") 11 | mom2:flipy() 12 | end 13 | -------------------------------------------------------------------------------- /cells/basic/diode.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | pcell.add_parameters( 3 | { "diodetype", "pn", posvals = set("pn", "np") }, 4 | { "width", 1000 }, 5 | { "height", 1000 }, 6 | { "extension", 100 } 7 | ) 8 | end 9 | 10 | function layout(diode, _P) 11 | geometry.rectangle(diode, generics.other("active"), _P.width, _P.height) 12 | geometry.rectangle(diode, generics.contact("active"), _P.width, _P.height) 13 | geometry.rectangle(diode, generics.other("soiopen"), _P.width + 2 * _P.extension, _P.height + 2 * _P.extension) 14 | --geometry.rectangle(diode, generics.diode(_P.diodetype), _P.width + 2 * _P.extension, _P.height + 2 * _P.extension) 15 | end 16 | -------------------------------------------------------------------------------- /cells/passive/inductor/spiral.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | pcell.add_parameters( 3 | { "turns", 3 }, 4 | { "width", 6000 }, 5 | { "spacing", 6000 }, 6 | { "innerradius", 50000 }, 7 | { "pointsperturn", 8 }, 8 | { "metalnum", -1 }, 9 | { "grid", 100 } 10 | ) 11 | end 12 | 13 | local function fix_to_grid(val, grid) 14 | if val < 0 then 15 | return grid * math.ceil(val / grid) 16 | else 17 | return grid * math.floor(val / grid) 18 | end 19 | end 20 | 21 | function layout(inductor, _P) 22 | local pitch = _P.width + _P.spacing 23 | local pathpts = {} 24 | local append = util.make_insert_xy(pathpts) 25 | local startangle = -math.pi / 4 26 | local numpoints = _P.turns * _P.pointsperturn 27 | 28 | local dir = math.pi / 2 29 | local x = fix_to_grid(_P.innerradius * math.cos(startangle), _P.grid) 30 | local y = fix_to_grid(_P.innerradius * math.sin(startangle), _P.grid) 31 | local addr = math.sqrt(1) * _P.innerradius 32 | for i = 1, numpoints do 33 | append(x, y) 34 | --addr = addr + pitch / 2 35 | --addr = addr + pitch / 10 36 | local dx = addr * math.cos(dir) 37 | local dy = addr * math.sin(dir) 38 | x = fix_to_grid(x + dx, _P.grid) 39 | y = fix_to_grid(y + dy, _P.grid) 40 | dir = dir + 2 * math.pi / _P.pointsperturn 41 | end 42 | --inductor:merge_into(geometry.any_angle_path(generics.metal(_P.metalnum), pathpts, _P.width, _P.grid)) 43 | geometry.path(inductor, generics.metal(_P.metalnum), pathpts, _P.width) 44 | --inductor:merge_into(geometry.rectangle(generics.metal(-2), 45 | -- fix_to_grid(math.sqrt(2) * (_P.innerradius + 0 * pitch), _P.grid), 46 | -- fix_to_grid(math.sqrt(2) * (_P.innerradius + 0 * pitch), _P.grid) 47 | --)) 48 | --inductor:merge_into(geometry.rectangle(generics.metal(-3), 49 | -- fix_to_grid(math.sqrt(2) * _P.innerradius + 2 * pitch, _P.grid), 50 | -- fix_to_grid(math.sqrt(2) * _P.innerradius + 2 * pitch, _P.grid) 51 | --)) 52 | end 53 | -------------------------------------------------------------------------------- /cells/passive/inductor/spiral_rectangular.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | pcell.add_parameters( 3 | { "turns(Number of Turns)", 3 }, 4 | { "width(Width)", 6000 }, 5 | { "spacing(Line Spacing)", 6000 }, 6 | { "innerdiameter(Inner Diameter)", 10000 }, 7 | { "metalnum(Conductor Metal)", -1, "integer" }, 8 | { "method(Method)", "rectangularyx" } 9 | ) 10 | end 11 | 12 | function layout(inductor, _P) 13 | local pathpts = {} 14 | local append = util.make_insert_xy(pathpts) 15 | local pitch = _P.width + _P.spacing 16 | for i = 1, _P.turns do 17 | local xy = (_P.innerdiameter + _P.width) / 2 + (i - 1) * pitch 18 | append( xy + 0.00 * pitch, -xy + 0.00 * pitch) 19 | append( xy + 0.00 * pitch, xy + 0.50 * pitch) 20 | append(-xy - 0.50 * pitch, xy + 0.50 * pitch) 21 | append(-xy - 0.50 * pitch, -xy - 1.00 * pitch) 22 | end 23 | geometry.path_midpoint(inductor, generics.metal(_P.metalnum), pathpts, _P.width, _P.method, true) 24 | geometry.rectangle(inductor, generics.metal(-2), 2 * math.floor(math.sqrt(2) * _P.innerdiameter / 2 / 2), 2 * math.floor(math.sqrt(2) * _P.innerdiameter / 2 / 2)) 25 | end 26 | -------------------------------------------------------------------------------- /cells/stdcells/1_inv_gate.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | pcell.add_parameters( 3 | { "subgate", "nand_gate", posvals = set("nand_gate", "nor_gate", "xor_gate") }, 4 | { "subgatefingers", 1 }, 5 | { "notfingers", 1 } 6 | ) 7 | pcell.inherit_parameters("stdcells/base") 8 | end 9 | 10 | function layout(gate, _P) 11 | local xpitch = _P.gatelength + _P.gatespace 12 | 13 | local subgatename = string.format("stdcells/%s", _P.subgate) 14 | 15 | local subgate_baseparameters = {} 16 | for k, v in pairs(_P) do 17 | if pcell.has_parameter(subgatename, k) then 18 | subgate_baseparameters[k] = v 19 | end 20 | end 21 | local subgateref = pcell.create_layout(subgatename, "subgate", util.add_options(subgate_baseparameters, { 22 | fingers = _P.subgatefingers, 23 | })) 24 | gate:merge_into(subgateref) 25 | 26 | local notgate_baseparameters = {} 27 | for k, v in pairs(_P) do 28 | if pcell.has_parameter("stdcells/not_gate", k) then 29 | notgate_baseparameters[k] = v 30 | end 31 | end 32 | local invref = pcell.create_layout("stdcells/not_gate", "inv", util.add_options(notgate_baseparameters, { 33 | fingers = _P.notfingers, 34 | shiftoutput = xpitch / 2, 35 | })) 36 | invref:abut_right(subgateref) 37 | gate:merge_into(invref) 38 | 39 | -- draw connection 40 | geometry.rectanglebltr(gate, generics.metal(1), 41 | subgateref:get_anchor("O") .. invref:get_anchor("I"):translate(xpitch - _P.sdwidth / 2 - _P.routingspace, 0), 42 | invref:get_anchor("I"):translate(xpitch - _P.sdwidth / 2 - _P.routingspace, _P.routingwidth) 43 | ) 44 | 45 | gate:inherit_alignment_box(subgateref) 46 | gate:inherit_alignment_box(invref) 47 | 48 | -- ports 49 | gate:add_port_with_anchor("A", generics.metalport(1), subgateref:get_anchor("A")) 50 | gate:add_port_with_anchor("B", generics.metalport(1), subgateref:get_anchor("B")) 51 | gate:add_port_with_anchor("O", generics.metalport(1), invref:get_anchor("O")) 52 | gate:add_port("VDD", generics.metalport(1), subgateref:get_anchor("VDD")) 53 | gate:add_port("VSS", generics.metalport(1), subgateref:get_anchor("VSS")) 54 | end 55 | -------------------------------------------------------------------------------- /cells/stdcells/21_gate.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | A --------------- GATE2 3 | GATE2 ---- O 4 | B2 ----- GATE1 --- GATE2 5 | GATE1 6 | B1 ----- GATE1 7 | ]] 8 | function parameters() 9 | pcell.add_parameters( 10 | { "gate1", "nand_gate" }, 11 | { "gate2", "nor_gate" } 12 | ) 13 | end 14 | 15 | function layout(gate, _P) 16 | local bp = pcell.get_parameters("stdcells/base"); 17 | 18 | local gate1ref = pcell.create_layout(string.format("stdcells/%s", _P.gate1), "gate1") 19 | local gate1 = gate:add_child(gate1ref, "gate1") 20 | 21 | local gate2ref = pcell.create_layout(string.format("stdcells/%s", _P.gate2), "gate2") 22 | local gate2 = gate:add_child(gate2ref, "gate2") 23 | gate2:abut_left(gate1) 24 | 25 | gate:inherit_alignment_box(gate1) 26 | gate:inherit_alignment_box(gate2) 27 | 28 | -- draw connections 29 | geometry.path(gate, generics.metal(1), 30 | geometry.path_points_yx(gate1:get_anchor("O"), { 31 | gate2:get_anchor("B") 32 | }), 33 | bp.sdwidth) 34 | 35 | --draw ports 36 | gate:add_port("A", generics.metalport(1), gate2:get_anchor("A")) 37 | gate:add_port("B1", generics.metalport(1), gate1:get_anchor("A")) 38 | gate:add_port("B2", generics.metalport(1), gate1:get_anchor("B")) 39 | gate:add_port("O", generics.metalport(1), gate2:get_anchor("O")) 40 | gate:add_port("VDD", generics.metalport(1), gate1:get_anchor("VDD")) 41 | gate:add_port("VSS", generics.metalport(1), gate1:get_anchor("VSS")) 42 | end 43 | -------------------------------------------------------------------------------- /cells/stdcells/and_gate.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | pcell.add_parameters( 3 | { "nandfingers", 1 }, 4 | { "notfingers", 1 } 5 | ) 6 | pcell.inherit_parameters("stdcells/base") 7 | end 8 | 9 | function layout(gate, _P) 10 | local baseparameters = {} 11 | for k, v in pairs(_P) do 12 | if pcell.has_parameter("stdcells/1_inv_gate", k) then 13 | baseparameters[k] = v 14 | end 15 | end 16 | local subgate = pcell.create_layout("stdcells/1_inv_gate", "and_gate", util.add_options(baseparameters, { 17 | subgate = "nand_gate", 18 | subgatefingers = _P.nandfingers, 19 | notfingers = _P.notfingers, 20 | })) 21 | gate:exchange(subgate) 22 | end 23 | -------------------------------------------------------------------------------- /cells/stdcells/buf.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | pcell.add_parameters( 3 | { "ifingers", 1 }, 4 | { "ofingers", 1 }, 5 | { "shiftinput1", 0 }, 6 | { "shiftinput2", 0 } 7 | ) 8 | pcell.inherit_parameters("stdcells/base") 9 | end 10 | 11 | function layout(gate, _P) 12 | local baseparameters = {} 13 | for name, value in pairs(_P) do 14 | if pcell.has_parameter("stdcells/not_gate", name) then 15 | baseparameters[name] = value 16 | end 17 | end 18 | local iinv = pcell.create_layout("stdcells/not_gate", "iinv", util.add_options(baseparameters, { 19 | fingers = _P.ifingers, 20 | shiftinput = _P.shiftinput1, 21 | shiftoutput = _P.gatelength / 2 + _P.gatespace / 2 22 | })) 23 | 24 | local oinv = pcell.create_layout("stdcells/not_gate", "oinv", util.add_options(baseparameters, { 25 | fingers = _P.ofingers, 26 | shiftinput = _P.shiftinput2, 27 | shiftoutput = _P.gatelength / 2 + _P.gatespace / 2 28 | })) 29 | oinv:abut_right(iinv) 30 | gate:merge_into(iinv) 31 | gate:merge_into(oinv) 32 | 33 | -- draw connection 34 | local ishift = _P.ifingers % 2 == 0 and 0 or 1 35 | geometry.path(gate, generics.metal(1), 36 | geometry.path_points_yx(iinv:get_anchor("O"), { 37 | oinv:get_anchor("I"), 38 | }), _P.sdwidth) 39 | 40 | gate:inherit_alignment_box(iinv) 41 | gate:inherit_alignment_box(oinv) 42 | 43 | -- anchors 44 | gate:add_anchor("in", iinv:get_anchor("I")) 45 | gate:add_anchor("iout", iinv:get_anchor("O")) 46 | gate:add_anchor("bout", oinv:get_anchor("O")) 47 | 48 | -- ports 49 | gate:add_port("I", generics.metalport(1), iinv:get_anchor("I")) 50 | gate:add_port("O", generics.metalport(1), oinv:get_anchor("O")) 51 | gate:add_port("VDD", generics.metalport(1), oinv:get_anchor("VDD")) 52 | gate:add_port("VSS", generics.metalport(1), oinv:get_anchor("VSS")) 53 | end 54 | -------------------------------------------------------------------------------- /cells/stdcells/colstop.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | pcell.add_parameter("fingers", 1) 3 | pcell.add_parameter("leftnotright", true) 4 | pcell.inherit_parameters("stdcells/base") 5 | end 6 | 7 | function layout(gate, _P) 8 | local gatecontactpos = { "dummy" } 9 | local sdcontacts 10 | if _P.leftnotright then 11 | sdcontacts = { "power", "unused" } 12 | else 13 | sdcontacts = { "unused", "power" } 14 | end 15 | local leftpolylines = {} 16 | local rightpolylines = {} 17 | for i = 1, _P.fingers do 18 | local entry = { length = _P.gatelength, space = _P.gatespace } 19 | if _P.leftnotright then 20 | leftpolylines[i] = entry 21 | else 22 | rightpolylines[i] = entry 23 | end 24 | end 25 | local baseparameters = {} 26 | for name, value in pairs(_P) do 27 | if pcell.has_parameter("stdcells/harness", name) then 28 | baseparameters[name] = value 29 | end 30 | end 31 | local harness = pcell.create_layout("stdcells/harness", "harness", util.add_options(baseparameters, { 32 | gatecontactpos = gatecontactpos, 33 | pcontactpos = sdcontacts, 34 | ncontactpos = sdcontacts, 35 | drawactive = false, 36 | drawgatecontacts = false, 37 | drawtopgcut = false, 38 | drawbotgcut = false, 39 | drawleftstopgate = _P.leftnotright, 40 | leftpolylines = leftpolylines, 41 | drawrightstopgate = not _P.leftnotright, 42 | rightpolylines = rightpolylines, 43 | })) 44 | gate:merge_into(harness) 45 | gate:inherit_alignment_box(harness) 46 | end 47 | -------------------------------------------------------------------------------- /cells/stdcells/dffnq.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | pcell.inherit_parameters("stdcells/dff", { 3 | "clockpolarity", 4 | "enable_Q", 5 | "enable_QN", 6 | "enable_set", 7 | "enable_reset", 8 | }) 9 | end 10 | 11 | function layout(gate, _P) 12 | local baseparameters = {} 13 | for name, value in pairs(_P) do 14 | if pcell.has_parameter("stdcells/dff", name) then 15 | baseparameters[name] = value 16 | end 17 | end 18 | local dff = pcell.create_layout("stdcells/dff", "dffnq", util.add_options(baseparameters, { 19 | clockpolarity = "negative", 20 | enable_Q = true, 21 | enable_QN = false, 22 | enable_set = false, 23 | enable_reset = false, 24 | })) 25 | gate:exchange(dff) 26 | end 27 | -------------------------------------------------------------------------------- /cells/stdcells/dffnrq.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | pcell.inherit_parameters("stdcells/dff", { 3 | "clockpolarity", 4 | "enable_Q", 5 | "enable_QN", 6 | "enable_set", 7 | "enable_reset", 8 | }) 9 | end 10 | 11 | function layout(gate, _P) 12 | local baseparameters = {} 13 | for name, value in pairs(_P) do 14 | if pcell.has_parameter("stdcells/harness", name) then 15 | baseparameters[name] = value 16 | end 17 | end 18 | local dff = pcell.create_layout("stdcells/dff", "dffnrq", util.add_options(baseparameters, { 19 | clockpolarity = "negative", 20 | enable_Q = true, 21 | enable_QN = false, 22 | enable_set = false, 23 | enable_reset = true, 24 | })) 25 | gate:exchange(dff) 26 | end 27 | -------------------------------------------------------------------------------- /cells/stdcells/dffnrsq.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | pcell.inherit_parameters("stdcells/dff", { 3 | "clockpolarity", 4 | "enable_Q", 5 | "enable_QN", 6 | "enable_set", 7 | "enable_reset", 8 | }) 9 | end 10 | 11 | function layout(gate, _P) 12 | local baseparameters = {} 13 | for name, value in pairs(_P) do 14 | if pcell.has_parameter("stdcells/harness", name) then 15 | baseparameters[name] = value 16 | end 17 | end 18 | local dff = pcell.create_layout("stdcells/dff", "dffnrsq", util.add_options(baseparameters, { 19 | clockpolarity = "negative", 20 | enable_Q = true, 21 | enable_QN = false, 22 | enable_set = true, 23 | enable_reset = true, 24 | })) 25 | gate:exchange(dff) 26 | end 27 | -------------------------------------------------------------------------------- /cells/stdcells/dffnsq.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | pcell.inherit_parameters("stdcells/dff", { 3 | "clockpolarity", 4 | "enable_Q", 5 | "enable_QN", 6 | "enable_set", 7 | "enable_reset", 8 | }) 9 | end 10 | 11 | function layout(gate, _P) 12 | local baseparameters = {} 13 | for name, value in pairs(_P) do 14 | if pcell.has_parameter("stdcells/dff", name) then 15 | baseparameters[name] = value 16 | end 17 | end 18 | local dff = pcell.create_layout("stdcells/dff", "dffnsq", util.add_options(baseparameters, { 19 | clockpolarity = "negative", 20 | enable_Q = true, 21 | enable_QN = false, 22 | enable_set = true, 23 | enable_reset = false, 24 | })) 25 | gate:exchange(dff) 26 | end 27 | -------------------------------------------------------------------------------- /cells/stdcells/dffpq.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | pcell.inherit_parameters("stdcells/dff", { 3 | "clockpolarity", 4 | "enable_Q", 5 | "enable_QN", 6 | "enable_set", 7 | "enable_reset", 8 | }) 9 | end 10 | 11 | function layout(gate, _P) 12 | local baseparameters = {} 13 | for name, value in pairs(_P) do 14 | if pcell.has_parameter("stdcells/harness", name) then 15 | baseparameters[name] = value 16 | end 17 | end 18 | local dff = pcell.create_layout("stdcells/dff", "dffpq", util.add_options(baseparameters, { 19 | clockpolarity = "positive", 20 | enable_Q = true, 21 | enable_QN = false, 22 | enable_set = false, 23 | enable_reset = false, 24 | })) 25 | gate:exchange(dff) 26 | end 27 | -------------------------------------------------------------------------------- /cells/stdcells/dffprq.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | pcell.inherit_parameters("stdcells/dff", { 3 | "clockpolarity", 4 | "enable_Q", 5 | "enable_QN", 6 | "enable_set", 7 | "enable_reset", 8 | }) 9 | end 10 | 11 | function layout(gate, _P) 12 | local baseparameters = {} 13 | for name, value in pairs(_P) do 14 | if pcell.has_parameter("stdcells/dff", name) then 15 | baseparameters[name] = value 16 | end 17 | end 18 | local dff = pcell.create_layout("stdcells/dff", "dffprq", util.add_options(baseparameters, { 19 | clockpolarity = "positive", 20 | enable_Q = true, 21 | enable_QN = false, 22 | enable_set = false, 23 | enable_reset = true, 24 | })) 25 | gate:exchange(dff) 26 | end 27 | -------------------------------------------------------------------------------- /cells/stdcells/dffprsq.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | pcell.inherit_parameters("stdcells/dff", { 3 | "clockpolarity", 4 | "enable_Q", 5 | "enable_QN", 6 | "enable_set", 7 | "enable_reset", 8 | }) 9 | end 10 | 11 | function layout(gate, _P) 12 | local baseparameters = {} 13 | for name, value in pairs(_P) do 14 | if pcell.has_parameter("stdcells/dff", name) then 15 | baseparameters[name] = value 16 | end 17 | end 18 | local dff = pcell.create_layout("stdcells/dff", "dfprsq", util.add_options(baseparameters, { 19 | clockpolarity = "positive", 20 | enable_Q = true, 21 | enable_QN = false, 22 | enable_set = true, 23 | enable_reset = true, 24 | })) 25 | gate:exchange(dff) 26 | end 27 | -------------------------------------------------------------------------------- /cells/stdcells/dffpsq.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | pcell.inherit_parameters("stdcells/dff", { 3 | "clockpolarity", 4 | "enable_Q", 5 | "enable_QN", 6 | "enable_set", 7 | "enable_reset", 8 | }) 9 | end 10 | 11 | function layout(gate, _P) 12 | local baseparameters = {} 13 | for name, value in pairs(_P) do 14 | if pcell.has_parameter("stdcells/dff", name) then 15 | baseparameters[name] = value 16 | end 17 | end 18 | local dff = pcell.create_layout("stdcells/dff", "dffpsq", util.add_options(baseparameters, { 19 | clockpolarity = "positive", 20 | enable_Q = true, 21 | enable_QN = false, 22 | enable_set = true, 23 | enable_reset = false, 24 | })) 25 | gate:exchange(dff) 26 | end 27 | -------------------------------------------------------------------------------- /cells/stdcells/endcell.lua: -------------------------------------------------------------------------------- 1 | function layout(cell, _P) 2 | local bp = pcell.get_parameters("stdcells/base") 3 | local xpitch = bp.gatespace + bp.gatelength 4 | local separation = bp.numinnerroutes * bp.routingwidth + (bp.numinnerroutes + 1) * bp.routingspace 5 | 6 | --geometry.rectangle(cell, generics.other("gate"), bp.gatelength, separation + bp.pwidth + bp.nwidth, 0, 0, 5, 1, xpitch, 0) 7 | end 8 | -------------------------------------------------------------------------------- /cells/stdcells/fill.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | pcell.add_parameters( 3 | { "fingers", 1 } 4 | ) 5 | pcell.inherit_parameters("stdcells/base") 6 | end 7 | 8 | function layout(gate, _P) 9 | local xpitch = _P.gatespace + _P.gatelength 10 | 11 | local gatecontactpos = {} 12 | for i = 1, _P.fingers do 13 | gatecontactpos[i] = "dummy" 14 | end 15 | 16 | local contactpos = {} 17 | for i = 1, _P.fingers + 1 do 18 | contactpos[i] = "unused" 19 | end 20 | local baseparameters = {} 21 | for name, value in pairs(_P) do 22 | if pcell.has_parameter("stdcells/harness", name) then 23 | baseparameters[name] = value 24 | end 25 | end 26 | local harness = pcell.create_layout("stdcells/harness", "mosfets", util.add_options(baseparameters, { 27 | gatecontactpos = gatecontactpos, 28 | pcontactpos = contactpos, 29 | ncontactpos = contactpos, 30 | })) 31 | gate:merge_into(harness) 32 | gate:inherit_alignment_box(harness) 33 | end 34 | -------------------------------------------------------------------------------- /cells/stdcells/half_adder.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | CO = A & B 3 | S = A XOR B 4 | --]] 5 | function layout(gate, _P) 6 | local bp = pcell.get_parameters("stdcells/base"); 7 | 8 | local andgate = pcell.create_layout("stdcells/and_gate", "and_gate") 9 | gate:merge_into(andgate) 10 | gate:inherit_alignment_box(andgate) 11 | 12 | local isogate = pcell.create_layout("stdcells/isogate", "isogate") 13 | isogate:abut_right(andgate) 14 | gate:merge_into(isogate:copy()) 15 | 16 | local xorgate = pcell.create_layout("stdcells/xor_gate", "xorgate") 17 | xorgate:abut_right(isogate) 18 | gate:merge_into(xorgate) 19 | gate:inherit_alignment_box(xorgate) 20 | 21 | geometry.path(gate, generics.metal(2), 22 | geometry.path_points_xy(andgate:get_anchor("A"), { 23 | xorgate:get_anchor("A") 24 | }), bp.sdwidth) 25 | geometry.viabltr(gate, 1, 2, 26 | andgate:get_anchor("A"):translate(-bp.sdwidth / 2, -bp.sdwidth / 2), 27 | andgate:get_anchor("A"):translate( bp.sdwidth / 2, bp.sdwidth / 2) 28 | ) 29 | 30 | geometry.path(gate, generics.metal(2), { 31 | andgate:get_anchor("B"), xorgate:get_anchor("B") 32 | }, bp.sdwidth) 33 | geometry.viabltr(gate, 1, 2, 34 | andgate:get_anchor("B"):translate(-bp.sdwidth / 2, -bp.sdwidth / 2), 35 | andgate:get_anchor("B"):translate( bp.sdwidth / 2, bp.sdwidth / 2) 36 | ) 37 | 38 | gate:add_port_with_anchor("A", generics.metalport(1), andgate:get_anchor("A")) 39 | gate:add_port_with_anchor("B", generics.metalport(1), andgate:get_anchor("B")) 40 | gate:add_port_with_anchor("COUT", generics.metalport(1), andgate:get_anchor("O")) 41 | gate:add_port("S", generics.metalport(1), xorgate:get_anchor("O")) 42 | end 43 | -------------------------------------------------------------------------------- /cells/stdcells/isogate.lua: -------------------------------------------------------------------------------- 1 | function config() 2 | pcell.set_property("hidden", true) 3 | end 4 | 5 | function parameters() 6 | pcell.inherit_parameters("stdcells/base") 7 | end 8 | 9 | function layout(gate, _P) 10 | local xpitch = _P.gatespace + _P.gatelength 11 | 12 | local baseparameters = {} 13 | for k, v in pairs(_P) do 14 | if pcell.has_parameter("stdcells/harness", k) then 15 | baseparameters[k] = v 16 | end 17 | end 18 | local harness = pcell.create_layout("stdcells/harness", "mosfets", util.add_options(baseparameters, { 19 | gatecontactpos = { "dummy" }, 20 | pcontactpos = { "power", "power" }, 21 | ncontactpos = { "power", "power" }, 22 | pwidthoffset = _P.pwidthoffset, 23 | nwidthoffset = _P.nwidthoffset, 24 | drawdummyactivecontacts = false, 25 | })) 26 | gate:merge_into(harness) 27 | 28 | gate:inherit_alignment_box(harness) 29 | 30 | gate:add_port("VDD", generics.metalport(1), harness:get_area_anchor("PRp").bl) 31 | gate:add_port("VSS", generics.metalport(1), harness:get_area_anchor("PRn").bl) 32 | 33 | -- center gate 34 | gate:translate(xpitch / 2, 0) 35 | end 36 | -------------------------------------------------------------------------------- /cells/stdcells/leftcolstop.lua: -------------------------------------------------------------------------------- 1 | function layout(colstop) 2 | local cell = pcell.create_layout("stdcells/colstop", "leftcolstop", { fingers = 1 }) 3 | colstop:exchange(cell) 4 | end 5 | -------------------------------------------------------------------------------- /cells/stdcells/mux.lua: -------------------------------------------------------------------------------- 1 | function layout(gate, _P) 2 | local bp = pcell.get_parameters("stdcells/base") 3 | local xpitch = bp.gatespace + bp.gatelength 4 | 5 | local gatecontactpos = { 6 | "upper", "lower", "center" 7 | } 8 | 9 | local contactpos = { "power", "inner", "inner", "power" } 10 | local harness = pcell.create_layout("stdcells/harness", "harness", { 11 | gatecontactpos = gatecontactpos, 12 | pcontactpos = contactpos, 13 | ncontactpos = contactpos, 14 | }) 15 | gate:merge_into(harness) 16 | gate:inherit_alignment_box(harness) 17 | 18 | -- ports 19 | gate:add_port_with_anchor("A", generics.metalport(1), harness:get_area_anchor("G1").bl) 20 | gate:add_port_with_anchor("B", generics.metalport(1), harness:get_area_anchor("G1").bl) 21 | gate:add_port_with_anchor("O", generics.metalport(1), point.create((3 + 1) * xpitch / 2, 0)) 22 | gate:add_port("VDD", generics.metalport(1), harness:get_area_anchor("PRp").bl) 23 | gate:add_port("VSS", generics.metalport(1), harness:get_area_anchor("PRn").bl) 24 | end 25 | -------------------------------------------------------------------------------- /cells/stdcells/nand_gate.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | pcell.add_parameter("fingers", 1) 3 | pcell.add_parameter("shiftoutput", 0) 4 | pcell.inherit_parameters("stdcells/base") 5 | end 6 | 7 | function layout(gate, _P) 8 | local baseparameters = {} 9 | for k, v in pairs(_P) do 10 | if pcell.has_parameter("stdcells/nand_nor_layout_base", k) then 11 | baseparameters[k] = v 12 | end 13 | end 14 | local base = pcell.create_layout("stdcells/nand_nor_layout_base", "nand_gate", util.add_options(baseparameters, { 15 | fingers = _P.fingers, 16 | gatetype = "nand", 17 | shiftoutput = _P.shiftoutput 18 | })) 19 | gate:exchange(base) 20 | end 21 | -------------------------------------------------------------------------------- /cells/stdcells/nor_gate.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | pcell.add_parameter("fingers", 1) 3 | pcell.add_parameter("shiftoutput", 0) 4 | pcell.inherit_parameters("stdcells/base") 5 | end 6 | 7 | function layout(gate, _P) 8 | local baseparameters = {} 9 | for k, v in pairs(_P) do 10 | if pcell.has_parameter("stdcells/nand_nor_layout_base", k) then 11 | baseparameters[k] = v 12 | end 13 | end 14 | local base = pcell.create_layout("stdcells/nand_nor_layout_base", "nand_gate", util.add_options(baseparameters, { 15 | fingers = _P.fingers, 16 | gatetype = "nor", 17 | shiftoutput = _P.shiftoutput 18 | })) 19 | gate:exchange(base) 20 | end 21 | -------------------------------------------------------------------------------- /cells/stdcells/or_gate.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | pcell.add_parameters( 3 | { "norfingers", 1 }, 4 | { "notfingers", 1 } 5 | ) 6 | pcell.inherit_parameters("stdcells/base") 7 | end 8 | 9 | function layout(gate, _P) 10 | local baseparameters = {} 11 | for k, v in pairs(_P) do 12 | if pcell.has_parameter("stdcells/1_inv_gate", k) then 13 | baseparameters[k] = v 14 | end 15 | end 16 | local subgate = pcell.create_layout("stdcells/1_inv_gate", "and_gate", util.add_options(baseparameters, { 17 | subgate = "nor_gate", 18 | subgatefingers = _P.norfingers, 19 | notfingers = _P.notfingers, 20 | })) 21 | gate:exchange(subgate) 22 | end 23 | -------------------------------------------------------------------------------- /cells/stdcells/rightcolstop.lua: -------------------------------------------------------------------------------- 1 | function layout(colstop) 2 | local cell = pcell.create_layout("stdcells/colstop", "rightcolstop", { leftnotright = false, fingers = 1 }) 3 | colstop:exchange(cell) 4 | end 5 | -------------------------------------------------------------------------------- /cells/stdcells/tbuf.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | pcell.add_parameters( 3 | { "ifingers", 1 }, 4 | { "ofingers", 1 } 5 | ) 6 | pcell.inherit_parameters("stdcells/base") 7 | end 8 | 9 | function layout(gate, _P) 10 | -- inverter 11 | local inv = pcell.create_layout("stdcells/not_gate", "inv", { inputpos = "lower1", fingers = _P.ifingers }) 12 | gate:merge_into(inv) 13 | 14 | local isogate = pcell.create_layout("stdcells/isogate", "isogate") 15 | isogate:abut_right(inv) 16 | gate:merge_into(isogate) 17 | 18 | -- clocked inverter 19 | local cinv = pcell.create_layout("stdcells/cinv", "cinv", { fingers = _P.ofingers }) 20 | cinv:abut_right(isogate) 21 | gate:merge_into(cinv) 22 | 23 | -- connections 24 | geometry.path(gate, generics.metal(1), 25 | geometry.path_points_yx(inv:get_anchor("O"), { 26 | cinv:get_anchor("EP") 27 | }), _P.routingwidth) 28 | geometry.path(gate, generics.metal(2), { inv:get_anchor("I"), cinv:get_anchor("EN") }, _P.routingwidth) 29 | geometry.viabltr(gate, 1, 2, 30 | inv:get_anchor("I"):translate(-_P.gatelength / 2, -_P.routingwidth / 2), 31 | inv:get_anchor("I"):translate( _P.gatelength / 2, _P.routingwidth / 2) 32 | ) 33 | geometry.viabltr(gate, 1, 2, 34 | cinv:get_anchor("EN"):translate(-_P.gatelength / 2, -_P.routingwidth / 2), 35 | cinv:get_anchor("EN"):translate( _P.gatelength / 2, _P.routingwidth / 2) 36 | ) 37 | 38 | geometry.path(gate, generics.metal(2), { cinv:get_anchor("I"), point.combine_12(inv:get_anchor("I"), cinv:get_anchor("I")) }, _P.routingwidth) 39 | geometry.viabltr(gate, 1, 2, 40 | point.combine_12(inv:get_anchor("I"), cinv:get_anchor("I")):translate(-_P.gatelength / 2, -_P.routingwidth / 2), 41 | point.combine_12(inv:get_anchor("I"), cinv:get_anchor("I")):translate( _P.gatelength / 2, _P.routingwidth / 2) 42 | ) 43 | geometry.viabltr(gate, 1, 2, 44 | cinv:get_anchor("I"):translate(-_P.gatelength / 2, -_P.routingwidth / 2), 45 | cinv:get_anchor("I"):translate( _P.gatelength / 2, _P.routingwidth / 2) 46 | ) 47 | 48 | -- ports 49 | gate:add_port_with_anchor("EN", generics.metalport(1), inv:get_anchor("I")) 50 | gate:add_port_with_anchor("I", generics.metalport(1), cinv:get_anchor("I")) 51 | gate:add_port_with_anchor("O", generics.metalport(1), cinv:get_anchor("O")) 52 | gate:add_port("VDD", generics.metalport(1), isogate:get_anchor("VDD")) 53 | gate:add_port("VSS", generics.metalport(1), isogate:get_anchor("VSS")) 54 | end 55 | -------------------------------------------------------------------------------- /cells/stdcells/tie_high.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | pcell.add_parameters( 3 | { "fingers", 2, posvals = even() } 4 | ) 5 | pcell.inherit_parameters("stdcells/base") 6 | end 7 | 8 | function layout(cell, _P) 9 | local baseparameters = {} 10 | for name, value in pairs(_P) do 11 | if pcell.has_parameter("stdcells/tie_highlow", name) then 12 | baseparameters[name] = value 13 | end 14 | end 15 | local base = pcell.create_layout("stdcells/tie_highlow", "tie_high", util.add_options(baseparameters, { 16 | high = true, 17 | fingers = _P.fingers 18 | })) 19 | cell:exchange(base) 20 | end 21 | -------------------------------------------------------------------------------- /cells/stdcells/tie_low.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | pcell.add_parameters( 3 | { "fingers", 2, posvals = even() } 4 | ) 5 | pcell.inherit_parameters("stdcells/base") 6 | end 7 | 8 | function layout(cell, _P) 9 | local baseparameters = {} 10 | for name, value in pairs(_P) do 11 | if pcell.has_parameter("stdcells/tie_highlow", name) then 12 | baseparameters[name] = value 13 | end 14 | end 15 | local base = pcell.create_layout("stdcells/tie_highlow", "tie_low", util.add_options(baseparameters, { 16 | high = false, 17 | fingers = _P.fingers 18 | })) 19 | cell:exchange(base) 20 | end 21 | -------------------------------------------------------------------------------- /cells/transmitter/memory.lua: -------------------------------------------------------------------------------- 1 | function parameters() 2 | pcell.add_parameters( 3 | { "numlanes", 64 }, 4 | { "bitsperlane", 32 }, 5 | { "bitresolution", 8 } 6 | ) 7 | end 8 | 9 | function layout(memory, _P) 10 | local dffpref = pcell.create_layout("stdcells/dff", "dffp", { clockpolarity = "positive" }) 11 | local dffnref = pcell.create_layout("stdcells/dff", "dffn", { clockpolarity = "negative" }) 12 | local laneref = object.create("lane") 13 | local dffs = {} 14 | for j = 1, _P.bitresolution do 15 | for k = 1, _P.bitsperlane do 16 | local dff = laneref:add_child((k % 2 == 1) and dffpref or dffnref, string.format("dff_%d_%d", j, k)) 17 | if k > 1 then 18 | dff:move_anchor("left", dffs[(j - 1) * _P.bitsperlane + k - 1]:get_anchor("right")) 19 | elseif j > 1 then 20 | dff:move_anchor("bottom", dffs[(j - 2) * _P.bitsperlane + 1]:get_anchor("top")) 21 | end 22 | if j % 2 == 0 then 23 | dff:flipy() 24 | end 25 | dffs[(j - 1) * _P.bitsperlane + k] = dff 26 | -- connection to next dff 27 | if k > 1 then 28 | geometry.path(laneref, generics.metal(1), 29 | geometry.path_points_yx(dffs[(j - 1) * _P.bitsperlane + k - 1]:get_anchor("Q"), { 30 | dffs[(j - 1) * _P.bitsperlane + k]:get_anchor("D") 31 | }), 40 32 | ) 33 | end 34 | end 35 | if _P.bitsperlane > 1 then 36 | geometry.path(laneref, generics.metal(3), { 37 | dffs[(j - 1) * _P.bitsperlane + 1]:get_anchor("CLK"), 38 | dffs[(j - 1) * _P.bitsperlane + _P.bitsperlane]:get_anchor("CLK") 39 | }, 40) 40 | end 41 | laneref:add_anchor("D", dffs[(j - 1) * _P.bitsperlane + 1]:get_anchor("D")) 42 | end 43 | laneref:set_alignment_box( 44 | dffs[1]:get_anchor("bottomleft"), 45 | dffs[_P.bitresolution * _P.bitsperlane]:get_anchor("topright") 46 | ) 47 | 48 | local lanes = {} 49 | for i = 1, _P.numlanes do 50 | lanes[i] = memory:add_child(laneref, string.format("lane_%d", i)) 51 | if i % 2 == 0 then 52 | lanes[i]:flipy() 53 | end 54 | if i > 1 then 55 | lanes[i]:move_anchor("bottom", lanes[i - 1]:get_anchor("top")) 56 | end 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /doc/Makefile: -------------------------------------------------------------------------------- 1 | cells := ../cells/passive/capacitor/mom.lua ../cells/passive/inductor/octagonal.lua 2 | documents := presentation.pdf userguide.pdf techdoc.pdf techfiles.pdf celldesign.pdf export.pdf 3 | 4 | .PHONY: all 5 | all: ${documents} 6 | 7 | .PHONY: full 8 | full: 9 | @$(MAKE) all 10 | rm ${documents} 11 | @$(MAKE) all 12 | rm ${documents} 13 | @$(MAKE) all 14 | 15 | presentation.pdf: src/presentation/main.tex src/presentation/preamble.tex 16 | $(MAKE) -C src/presentation main.pdf 17 | mv src/presentation/main.pdf presentation.pdf 18 | 19 | userguide.pdf: src/userguide/main.tex src/preamble.tex 20 | $(MAKE) -C src/userguide main.pdf 21 | mv src/userguide/main.pdf userguide.pdf 22 | 23 | techdoc.pdf: src/techdoc/main.tex src/preamble.tex 24 | $(MAKE) -C src/techdoc main.pdf 25 | mv src/techdoc/main.pdf techdoc.pdf 26 | 27 | celldesign.pdf: src/celldesign/main.tex src/preamble.tex ${cells} src/celldesign/code/* 28 | $(MAKE) -C src/celldesign main.pdf 29 | mv src/celldesign/main.pdf celldesign.pdf 30 | 31 | techfiles.pdf: src/techfiles/main.tex src/preamble.tex 32 | $(MAKE) -C src/techfiles main.pdf 33 | mv src/techfiles/main.pdf techfiles.pdf 34 | 35 | export.pdf: src/export/main.tex src/preamble.tex 36 | $(MAKE) -C src/export main.pdf 37 | mv src/export/main.pdf export.pdf 38 | 39 | # in src directories 40 | main.pdf: 41 | lualatex -shell-escape main.tex 42 | 43 | .PHONY: clean 44 | clean: 45 | $(MAKE) -C src/presentation clean 46 | $(MAKE) -C src/userguide clean 47 | $(MAKE) -C src/techdoc clean 48 | $(MAKE) -C src/celldesign clean 49 | $(MAKE) -C src/techfiles clean 50 | -------------------------------------------------------------------------------- /doc/celldesign.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickschulz/openPCells/14f34e0a04d0e87ac7ac1027ab7522b20e90d074/doc/celldesign.pdf -------------------------------------------------------------------------------- /doc/export.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickschulz/openPCells/14f34e0a04d0e87ac7ac1027ab7522b20e90d074/doc/export.pdf -------------------------------------------------------------------------------- /doc/info/mosfet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickschulz/openPCells/14f34e0a04d0e87ac7ac1027ab7522b20e90d074/doc/info/mosfet.png -------------------------------------------------------------------------------- /doc/info/mosfet_complex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickschulz/openPCells/14f34e0a04d0e87ac7ac1027ab7522b20e90d074/doc/info/mosfet_complex.png -------------------------------------------------------------------------------- /doc/info/ringoscillator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickschulz/openPCells/14f34e0a04d0e87ac7ac1027ab7522b20e90d074/doc/info/ringoscillator.png -------------------------------------------------------------------------------- /doc/presentation.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickschulz/openPCells/14f34e0a04d0e87ac7ac1027ab7522b20e90d074/doc/presentation.pdf -------------------------------------------------------------------------------- /doc/src/Makefile: -------------------------------------------------------------------------------- 1 | main.pdf: main.tex 2 | lualatex -shell-escape main.tex 3 | 4 | .PHONY: clean 5 | clean: 6 | latexmk -C 7 | -------------------------------------------------------------------------------- /doc/src/celldesign/Makefile: -------------------------------------------------------------------------------- 1 | ../Makefile -------------------------------------------------------------------------------- /doc/src/celldesign/code/hierarchy_example.lua: -------------------------------------------------------------------------------- 1 | local toplevel = object.create("toplevel") 2 | local sub = object.create("sub") 3 | local subsub = object.create("subsub") 4 | sub:add_child(subsub, "subsub1") 5 | sub:add_child(subsub, "subsub2") 6 | toplevel:add_child(sub, "sub") 7 | -------------------------------------------------------------------------------- /doc/src/celldesign/code/merge_into_example.lua: -------------------------------------------------------------------------------- 1 | function layout(toplevel) 2 | local cell = -- get the layout from somewhere 3 | toplevel:merge_into(cell) 4 | toplevel:merge_into(cell:flatten()) 5 | toplevel:merge_into(cell:copy():flatten()) 6 | end 7 | -------------------------------------------------------------------------------- /doc/src/celldesign/code/ringoscillator.lua: -------------------------------------------------------------------------------- 1 | function layout(toplevel) 2 | local inverter = -- create inverter layout 3 | -- copy inverter and translate it 4 | local width = 1000 -- the width needs to be known 5 | local inverter1 = inverter:copy():translate(0 * width, 0) 6 | local inverter2 = inverter:copy():translate(1 * width, 0) 7 | local inverter3 = inverter:copy():translate(2 * width, 0) 8 | -- merge into toplevel 9 | toplevel:merge_into(inverter1) 10 | toplevel:merge_into(inverter2) 11 | toplevel:merge_into(inverter3) 12 | end 13 | -------------------------------------------------------------------------------- /doc/src/celldesign/code/ringoscillator_anchor.lua: -------------------------------------------------------------------------------- 1 | function layout(toplevel) 2 | local inverter = -- create inverter layout 3 | -- copy inverters 4 | local inverter1 = inverter:copy() 5 | local inverter2 = inverter:copy() 6 | local inverter3 = inverter:copy() 7 | 8 | -- get required displacement for inverter2 9 | local output1 = inverter1:get_anchor("output") 10 | local input2 = inverter2:get_anchor("input") 11 | -- translate inverter2 12 | local inverter2 = inverter2:translate(output1 - input2) 13 | 14 | -- get required displacement for inverter3 15 | local output2 = inverter2:get_anchor("output") 16 | local input3 = inverter3:get_anchor("input") 17 | -- translate inverter3 18 | local inverter3 = inverter3:translate(output2 - input3) 19 | 20 | -- merge inverters into toplevel 21 | toplevel:merge_into(inverter1) 22 | toplevel:merge_into(inverter2) 23 | toplevel:merge_into(inverter3) 24 | end 25 | -------------------------------------------------------------------------------- /doc/src/celldesign/code/ringoscillator_move_point.lua: -------------------------------------------------------------------------------- 1 | function layout(toplevel) 2 | local inverter = -- create inverter layout 3 | -- copy inverter and move it to the origin 4 | local inverter1 = inverter:copy() 5 | inverter1:move_point( 6 | inverter1:get_anchor("input"), 7 | point.create(0, 0) 8 | ) 9 | -- copy and translate inverter2 10 | local inverter2 = inverter:copy() 11 | inverter2:move_point( 12 | inverter2:get_anchor("input"), 13 | inverter1:get_anchor("output") 14 | ) 15 | -- copy and translate inverter3 16 | local inverter3 = inverter:copy() 17 | inverter3:move_point( 18 | inverter3:get_anchor("input"), 19 | inverter2:get_anchor("output") 20 | ) 21 | -- merge inverters into toplevel 22 | toplevel:merge_into(inverter1) 23 | toplevel:merge_into(inverter2) 24 | toplevel:merge_into(inverter3) 25 | end 26 | -------------------------------------------------------------------------------- /doc/src/celldesign/code/ringoscillator_nocopy.lua: -------------------------------------------------------------------------------- 1 | function layout(toplevel) 2 | local inverter = -- create inverter layout 3 | local width = 1000 -- the width needs to be known 4 | -- translate and merge into toplevel 5 | toplevel:merge_into(inverter) 6 | toplevel:merge_into(inverter:translate(width, 0)) 7 | toplevel:merge_into(inverter:translate(width, 0)) 8 | end 9 | -------------------------------------------------------------------------------- /doc/src/celldesign/code/simple_rectangle.lua: -------------------------------------------------------------------------------- 1 | -- define parameters 2 | function parameters() 3 | pcell.add_parameters( 4 | { "width", 100 }, 5 | { "height", 100 } 6 | ) 7 | end 8 | 9 | -- define layout 10 | function layout(obj, _P) 11 | -- create the shape and add it to the main object 12 | geometry.rectanglebltr( 13 | obj, 14 | generics.metal(1), 15 | point.create(0, 0), 16 | point.create(_P.width, _P.height) 17 | ) 18 | end 19 | -------------------------------------------------------------------------------- /doc/src/export/Makefile: -------------------------------------------------------------------------------- 1 | main.pdf: main.tex 2 | lualatex -shell-escape main.tex 3 | 4 | .PHONY: clean 5 | clean: 6 | latexmk -C 7 | -------------------------------------------------------------------------------- /doc/src/presentation/Makefile: -------------------------------------------------------------------------------- 1 | ../Makefile -------------------------------------------------------------------------------- /doc/src/presentation/main.auxlock: -------------------------------------------------------------------------------- 1 | \def \tikzexternallocked {0} 2 | -------------------------------------------------------------------------------- /doc/src/presentation/main.snm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickschulz/openPCells/14f34e0a04d0e87ac7ac1027ab7522b20e90d074/doc/src/presentation/main.snm -------------------------------------------------------------------------------- /doc/src/techdoc/Makefile: -------------------------------------------------------------------------------- 1 | ../Makefile -------------------------------------------------------------------------------- /doc/src/techfiles/Makefile: -------------------------------------------------------------------------------- 1 | ../Makefile -------------------------------------------------------------------------------- /doc/src/userguide/Makefile: -------------------------------------------------------------------------------- 1 | ../Makefile -------------------------------------------------------------------------------- /doc/techdoc.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickschulz/openPCells/14f34e0a04d0e87ac7ac1027ab7522b20e90d074/doc/techdoc.pdf -------------------------------------------------------------------------------- /doc/techfiles.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickschulz/openPCells/14f34e0a04d0e87ac7ac1027ab7522b20e90d074/doc/techfiles.pdf -------------------------------------------------------------------------------- /doc/userguide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickschulz/openPCells/14f34e0a04d0e87ac7ac1027ab7522b20e90d074/doc/userguide.pdf -------------------------------------------------------------------------------- /examples/autofill/main.lua: -------------------------------------------------------------------------------- 1 | local cell = object.create("toplevel") 2 | 3 | -- create a few shapes to show the autofill 4 | geometry.path_polygon(cell, generics.metal(1), { 5 | point.create(2500, 0), 6 | point.create(2500, 2000), 7 | point.create(4500, 2000), 8 | point.create(4500, 4000), 9 | point.create(2500, 6000), 10 | point.create(2000, 6000), 11 | point.create(2000, 3000), 12 | point.create(1000, 3000), 13 | }, 200) 14 | geometry.rectanglebltr(cell, generics.metal(1), 15 | point.create(500, 500), 16 | point.create(1500, 1500) 17 | ) 18 | 19 | -- collect the shape outlines from the cell 20 | local excludes = cell:get_shape_outlines(generics.metal(1)) 21 | -- add an offset (spacing) 22 | local exclude_offset = 200 23 | for i = 1, #excludes do 24 | local exclude = excludes[i] 25 | local new = util.offset_polygon(exclude, exclude_offset) 26 | excludes[i] = new 27 | end 28 | 29 | -- show the excludes in the layout 30 | for i = 1, #excludes do 31 | geometry.polygon(cell, generics.special(), excludes[i]) 32 | end 33 | 34 | -- create the rectangular fill on M1 with excludes 35 | geometry.rectangle_fill_in_boundary(cell, generics.metal(1), 36 | 100, 100, -- width/height 37 | 200, 200, -- xpitch/ypitch 38 | 0, 0, -- start offsets (x/y) 39 | util.rectangle_to_polygon(point.create(0, 0), point.create(7000, 7000)), -- target area 40 | excludes -- table with exclusion polygons 41 | ) 42 | -- rectangular fill on M2 without excludes, uses a different start offset 43 | geometry.rectangle_fill_in_boundary(cell, generics.metal(2), 44 | 100, 100, -- width/height 45 | 200, 200, -- xpitch/ypitch 46 | 100, 100, -- start offsets (x/y) 47 | util.rectangle_to_polygon(point.create(0, 0), point.create(7000, 7000)) 48 | ) 49 | 50 | return cell 51 | -------------------------------------------------------------------------------- /examples/autofill/run.sh: -------------------------------------------------------------------------------- 1 | ../../opc --export gds --technology opc --cellscript main.lua 2 | -------------------------------------------------------------------------------- /examples/cells/LC_oscillator.lua: -------------------------------------------------------------------------------- 1 | return pcell.create_layout("LC_oscillator/toplevel", "oscillator", { 2 | resonator_inductor_turns = 2, 3 | resonator_inductor_metal = -2, 4 | resonator_dlfgroundshield = false, 5 | resonator_fillmetals = util.range(1, 7), 6 | disable_all_fill = true, 7 | ccp_fingersperside = 16, 8 | ccp_pmosfingerwidth = 1000, 9 | ccp_nmosfingerwidth = 624, 10 | ccp_middledummyfingers = 2, 11 | ccp_outerdummyfingers = 4, 12 | ccp_gatelength = 250, 13 | ccp_gatespace = 280, 14 | ccp_oxidetype = 1, 15 | ccp_mosfetmarker = 1, 16 | ccp_pvthtype = 1, 17 | ccp_nvthtype = 1, 18 | ccp_activedummywidth = 80, 19 | ccp_activedummyspace = 240, 20 | ccp_outputoffset = 200, 21 | ccp_gatestrapwidth = 250, 22 | ccp_gatestrapspace = 54, 23 | ccp_drainstrapspace = 400, 24 | ccp_powerwidth = 200, 25 | ccp_powerspace = 80, 26 | ccp_gateext = 10, 27 | ccp_sdwidth = 150, 28 | ccp_crossingoffset = 100, 29 | ccp_drawpsubguardring = true, 30 | ccp_inlinedrainstrap = false, 31 | ccp_topviawidth = 500, 32 | ccp_crossingmetal = 5, 33 | ccp_drainmetal = 7, 34 | ccp_vtailshift = 1000, 35 | ccp_vtailwidth = 1000, 36 | ccp_vtailmetal = 5, 37 | ccp_vtaillinewidth = 300, 38 | ccp_vtaillinespace = 300, 39 | ccp_fetpowermetal = 3, 40 | ccp_vssmetal = 5, 41 | ccp_vsslinewidth = 1000, 42 | ccp_vssshift = 1300, 43 | ccp_vsswidth = 1000, 44 | ccp_vsslinewidth = 300, 45 | ccp_vsslinespace = 300, 46 | guardring_width = 200, 47 | guardring_xspace = 200, 48 | guardring_yspace = 200, 49 | guardring_xspacetomosfet = 400, 50 | guardring_yspacetomosfet = 400, 51 | guardring_soiopenextension = 100, 52 | guardring_implantextension = 100, 53 | guardring_wellextension = 100, 54 | }) 55 | -------------------------------------------------------------------------------- /examples/cells/comparator.lua: -------------------------------------------------------------------------------- 1 | -- FIXME: the comparator cell is fairly complicated and not thoroughly checked 2 | -- this layout has some bugs 3 | return pcell.create_layout("analog/strongARM_comparator", "comparator", { 4 | gatelength = 500, 5 | gatespace = 320, 6 | clockfingers = 4, 7 | clockdummyfingers = 1, 8 | clockfingerwidth = 1000, 9 | clockinputgatewidth = 400, 10 | clockinputgatespace = 400, 11 | inputfingers = 4, 12 | inputfingerwidth = 1000, 13 | --inputdummyfingers = 1, 14 | latchfingers = 8, 15 | latchnfingerwidth = 1000, 16 | latchpfingerwidth = 1000, 17 | --latchcrossingoffset = 0, 18 | --latchgatewidth = 0, 19 | --latchgatespace = 0, 20 | --invdummyfingers = 1, 21 | --resetfingers = 2, 22 | --inputclocksdspace = 0, 23 | --invskip = 200, 24 | --resetgatewidth = 0, 25 | --resetgatespace = 0, 26 | --bufferfingers = 2, 27 | buffernfingerwidth = 1000, 28 | bufferpfingerwidth = 1000, 29 | rslatchnfingerwidth = 1000, 30 | rslatchpfingerwidth = 1000, 31 | --gstrwidth = 0, 32 | --sdwidth = 0, 33 | powerwidth = 800, 34 | powerspace = 300, 35 | outerdummyfingers = 4, 36 | --alternativeclockconnection = true, 37 | }) 38 | -------------------------------------------------------------------------------- /examples/cells/current_starved_ringoscillator.lua: -------------------------------------------------------------------------------- 1 | return pcell.create_layout("analog/current_starved_ringoscillator", "oscillator", { 2 | gatelength = 800, 3 | gatespace = 450, 4 | invfingers = 2, 5 | numinv = 5, 6 | pmosdiodefingers = 4, 7 | pmoszerofingers = 9, 8 | pmostunefingers = 2, 9 | pmosseparationfingers = 3, 10 | nmoscurrentfingers = 2, 11 | nmosdiodefingers = 4, 12 | mosdummieseverynth = 2, 13 | pfingerwidth = 2500, 14 | nfingerwidth = 1800, 15 | pfingercontactwidth = 1000, 16 | nfingercontactwidth = 1000, 17 | gstwidth = 400, 18 | gstspace = 600, 19 | powerwidth = 800, 20 | powerspace = 200, 21 | bufspacers = 2, 22 | buffingers = 4, 23 | drawguardrings = true, 24 | guardringwidth = 800, 25 | guardringspace = 800, 26 | }) 27 | -------------------------------------------------------------------------------- /examples/cells/mosfet.lua: -------------------------------------------------------------------------------- 1 | return pcell.create_layout("basic/mosfet", "mosfet", { 2 | channeltype = "pmos", 3 | flippedwell = false, 4 | vthtype = 1, 5 | oxidetype = 1, 6 | gatelength = 500, 7 | gatespace = 320, 8 | fingerwidth = 2000, 9 | fingers = 8, 10 | sdwidth = 200, 11 | drawtopgate = true, 12 | topgatewidth = 200, 13 | topgatespace = 200, 14 | sourcemetal = 1, 15 | connectsource = true, 16 | connectsourcewidth = 300, 17 | connectsourcespace = 200, 18 | drainmetal = 3, 19 | connectdrain = true, 20 | connectdrainwidth = 300, 21 | connectdrainspace = 200, 22 | extendall = 200, 23 | drawguardring = true, 24 | guardringsep = 1000, 25 | guardringfillwell = true, 26 | }) 27 | -------------------------------------------------------------------------------- /examples/cells/ringoscillator.lua: -------------------------------------------------------------------------------- 1 | local toplevel = object.create("toplevel") 2 | 3 | local oscillator1 = pcell.create_layout("analog/ringoscillator", "oscillator1", { 4 | invfingers = 4, 5 | numinv = 5, 6 | invdummies = 1, 7 | gatelength = 500, 8 | gatespace = 320, 9 | pfingerwidth = 2600, 10 | nfingerwidth = 1800, 11 | gatestrapwidth = 200, 12 | gatestrapspace = 200, 13 | sdwidth = 200, 14 | powerwidth = 800, 15 | powerspace = 200, 16 | connectionwidth = 200, 17 | feedbackmetal = 3, 18 | ngateext = 200, 19 | pgateext = 200, 20 | }) 21 | toplevel:add_child(oscillator1, "oscillator1") 22 | 23 | return toplevel 24 | -------------------------------------------------------------------------------- /examples/cells/run.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | ../../opc --technology opc --export gds --cellscript mosfet.lua --filename mosfet 4 | ../../opc --technology opc --export gds --cellscript ringoscillator.lua --filename ringoscillator 5 | ../../opc --technology opc --export gds --cellscript current_starved_ringoscillator.lua --filename current_starved_ringoscillator --enable-dprint 6 | ../../opc --technology opc --export gds --cellscript comparator.lua --filename comparator 7 | ../../opc --technology opc --export gds --cellscript LC_oscillator.lua --filename LC_oscillator --enable-fallback-vias 8 | -------------------------------------------------------------------------------- /examples/digital/run.sh: -------------------------------------------------------------------------------- 1 | lua generate.lua 2 | ../../opc --export gds --technology opc --cellscript digital.lua 3 | -------------------------------------------------------------------------------- /examples/place_and_route_automatic/generate_cell.lua: -------------------------------------------------------------------------------- 1 | local cellname = args[1] 2 | return pcell.create_layout(string.format("verilogimport/%s", cellname), "cell") 3 | -------------------------------------------------------------------------------- /examples/place_and_route_automatic/place_route_generate.lua: -------------------------------------------------------------------------------- 1 | if not args[1] then 2 | error("no target given") 3 | end 4 | 5 | local module = args[1] 6 | local exporttype = "gds" 7 | 8 | local netlist = verilog.read_parse_file(string.format("%s.v", module)) 9 | 10 | verilogprocessor.write_spice_netlist(string.format("%s_netlist.sp", module), netlist) 11 | 12 | local cellinfo = verilogprocessor.read_cellinfo_from_file("cellinfo.lua") 13 | local ignorednets = { -- insert names of nets that should be ignored 14 | "clk", 15 | } 16 | local circuit = verilogprocessor.collect_nets_cells(netlist, cellinfo, ignorednets) 17 | 18 | local utilization = 0.6 19 | local numrows = 12 20 | local floorplan = placement.create_floorplan_fixed_rows(circuit, utilization, numrows) 21 | local rows = placement.optimize(circuit, floorplan) 22 | --local plan = { 23 | -- { "inv", "nand1", "dff_out" }, 24 | -- { "nand2", "dff_buf" }, 25 | -- { "nand3", "dff_in" }, 26 | --} 27 | --local plan = { 28 | -- { "inv1", }, 29 | -- { "inv2" } 30 | --} 31 | --local rows = placement.manual(circuit, plan) 32 | placement.insert_filler_names(rows, floorplan.floorplan_width) 33 | 34 | -- hack: insert fill at the left side 35 | -- this is done to ensure that routing works if a dff is there, since their gates extend to the left 36 | -- this will be fixed and removed at some point 37 | for i in ipairs(rows) do 38 | table.insert(rows[i], 1, { 39 | reference = "isogate", 40 | instance = string.format("hackfill_%i", i), 41 | width = 1 42 | }) 43 | end 44 | floorplan.floorplan_width = floorplan.floorplan_width + 1 45 | 46 | -- this value can be (at least in theory) changed in the generated layout, but the router assumes this many tracks 47 | -- this means that reducing this value CAN work, but only increasing it will work certainly 48 | local pnumtracks = 4 49 | local nnumtracks = 4 50 | local numinnertracks = 3 51 | 52 | local routes = routing.basic(circuit, rows, numinnertracks, pnumtracks, nnumtracks, floorplan) 53 | 54 | local filename = generator.get_cell_filename("verilogimport", "verilogimport", module) 55 | print(string.format("writing to file '%s'", filename)) 56 | local file = io.open(filename, "w") 57 | generator.digital(file, rows, routes, numinnertracks, pnumtracks, nnumtracks) 58 | file:close() 59 | -------------------------------------------------------------------------------- /examples/place_and_route_automatic/run.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | CELL=serial_ctrl 4 | 5 | ../../opc --import-verilog place_route_generate.lua ${CELL} 6 | ../../opc --technology GF22FDSOI --export gds --cellscript generate_cell.lua --cellpath verilogimport ${CELL} 7 | -------------------------------------------------------------------------------- /examples/svg/gilfoyle.lua: -------------------------------------------------------------------------------- 1 | local cell = object.create("gilfoyle") 2 | 3 | cell:merge_into(pcell.create_layout("auxiliary/svg2layout", "_svg", { 4 | filename = "gilfoyle.svg", 5 | scale = 10, 6 | grid = 1, 7 | allow45 = true, 8 | inverty = true, 9 | })) 10 | 11 | return cell 12 | -------------------------------------------------------------------------------- /examples/svg/pineapple.lua: -------------------------------------------------------------------------------- 1 | local cell = object.create("pineapple") 2 | 3 | cell:merge_into(pcell.create_layout("auxiliary/svg2layout", "_svg", { 4 | filename = "pineapple.svg", 5 | scale = 1, 6 | grid = 1, 7 | allow45 = true, 8 | })) 9 | 10 | return cell 11 | -------------------------------------------------------------------------------- /examples/svg/run.sh: -------------------------------------------------------------------------------- 1 | OPC=../../opc 2 | 3 | ${OPC} --technology opc --export gds --cellscript pineapple.lua --filename pineapple 4 | ${OPC} --technology opc --export gds --cellscript talentandsweat.lua --filename talentandsweat 5 | ${OPC} --technology opc --export gds --cellscript gilfoyle.lua --filename gilfoyle 6 | -------------------------------------------------------------------------------- /examples/svg/talentandsweat.lua: -------------------------------------------------------------------------------- 1 | local cell = object.create("talentandsweat") 2 | 3 | cell:merge_into(pcell.create_layout("auxiliary/svg2layout", "_svg", { 4 | filename = "talentandsweat.svg", 5 | scale = 120, 6 | grid = 1, 7 | allow45 = true, 8 | inverty = true, 9 | })) 10 | 11 | return cell 12 | -------------------------------------------------------------------------------- /export/debug/init.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | local __content = {} 4 | 5 | function M.finalize() 6 | return table.concat(__content, "\n") 7 | end 8 | 9 | function M.get_techexport() 10 | return "raw" 11 | end 12 | 13 | function M.get_extension() 14 | return "debug" 15 | end 16 | 17 | function M.get_layer(S) 18 | return S:get_lpp():str() 19 | end 20 | 21 | function M.write_rectangle(layer, bl, tr) 22 | local xbot, ybot = bl:unwrap() 23 | local xtop, ytop = tr:unwrap() 24 | table.insert(__content, string.format("rect (%s): (%d, %d) (%d, %d)", layer, xbot, ybot, xtop, ytop)) 25 | end 26 | 27 | function M.write_polygon(layer, pts) 28 | local t = {} 29 | for _, pt in ipairs(pts) do 30 | local x, y = pt:unwrap() 31 | table.insert(t, string.format("(%d, %d)", x, y)) 32 | end 33 | table.insert(__content, string.format("poly (%s): %s", layer, table.concat(t, " "))) 34 | end 35 | 36 | function M.write_cell_reference(identifier, instname, origin) 37 | table.insert(__content, string.format("ref (%s): (%d, %d)", identifier, origin:getx(), origin:gety())) 38 | end 39 | 40 | function M.at_begin_cell(cellname) 41 | table.insert(__content, string.format("cell (%s) >", cellname)) 42 | end 43 | 44 | function M.at_end_cell() 45 | table.insert(__content, "<\n") 46 | end 47 | 48 | return M 49 | -------------------------------------------------------------------------------- /export/magic/init.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | function M.get_extension() 4 | return "mag" 5 | end 6 | 7 | local __technology = "DUMMYTECH" 8 | 9 | function M.set_options(opt) 10 | for i = 1, #opt do 11 | local arg = opt[i] 12 | if arg == "-T" or arg == "--technology" then 13 | if i < #opt then 14 | __technology = opt[i + 1] 15 | else 16 | error("magic export: --technology: argument expected") 17 | end 18 | i = i + 1 19 | end 20 | end 21 | end 22 | 23 | local __content = {} 24 | 25 | function M.finalize() 26 | return table.concat(__content, "\n") 27 | end 28 | 29 | function M.at_begin() 30 | table.insert(__content, string.format("%s", "magic")) 31 | table.insert(__content, string.format("tech %s", __technology)) 32 | table.insert(__content, string.format("timestamp %s", os.time())) 33 | end 34 | 35 | function M.at_end() 36 | table.insert(__content, string.format("%s", "<< end >>")) 37 | end 38 | 39 | function M.write_rectangle(layer, bl, tr) 40 | local grid = 1000 41 | bl.x = bl.x * grid 42 | bl.y = bl.y * grid 43 | tr.x = tr.x * grid 44 | tr.y = tr.y * grid 45 | table.insert(__content, string.format("<< %s >>", layer.layer)) 46 | table.insert(__content, string.format("rect %d %d %d %d", math.floor(bl.x), math.floor(bl.y), math.floor(tr.x), math.floor(tr.y))) 47 | end 48 | 49 | function M.write_triangle(layer, pt1, pt2, pt3) 50 | print("write_triangle is not finished, as at that time I did not know the exact required format. This should be trivial to fix") 51 | end 52 | 53 | function M.write_port(name, layer, where, sizehint) 54 | print("write_port is not finished, as at that time I did not know the exact required format. This should be trivial to fix") 55 | end 56 | 57 | return M 58 | -------------------------------------------------------------------------------- /interface/virtuoso/backup.il: -------------------------------------------------------------------------------- 1 | procedure(OPCCreateCellBackup() 2 | let( 3 | ( 4 | (path lsprintf("%s/%s" getShellEnvVar("HOME") "opcbackups")) 5 | ) 6 | unless(isDir(path) 7 | createDir(path) 8 | ) 9 | let( 10 | ( 11 | (cv geGetEditCellView()) 12 | ) 13 | OPCExportCell(lsprintf("%s/%s_%s.lua" path cv->libName cv->cellName)) 14 | ) 15 | ) 16 | ) 17 | 18 | procedure(OPCRestoreCellBackup() 19 | let( 20 | ( 21 | (path lsprintf("%s/%s" getShellEnvVar("HOME") "opcbackups")) 22 | ) 23 | if(isDir(path) 24 | then 25 | let( 26 | ( 27 | (cv geGetEditCellView()) 28 | filename 29 | ) 30 | filename = lsprintf("%s/%s_%s.lua" path cv->libName cv->cellName) 31 | if(isFile(filename) 32 | then 33 | OPCUpdateCellscriptCallback(filename ?hierarchical nil) 34 | else 35 | hiDisplayAppDBox( 36 | ?name 'OPCInfoDialog 37 | ?dboxBanner "openPCells" 38 | ?dboxText lsprintf("no opc backup for this cell (%s) found" filename) 39 | ?dialogType hicWarningDialog 40 | ?dialogStyle 'modeless 41 | ?buttonLayout 'Close 42 | ) 43 | ) 44 | ) 45 | else 46 | ) 47 | ) 48 | ) 49 | -------------------------------------------------------------------------------- /interface/virtuoso/cdsinit.il.sample: -------------------------------------------------------------------------------- 1 | ; this is a sample .cdsinit that shows how to set up openPCells with cadence virtuoso 2 | 3 | ; the used technology has to be defined, this will be passed verbatim to opc 4 | ; so if you call opc like this: opc --technology tech42 ... 5 | ; then OPCTech should be "tech42" 6 | OPCTech = "tech42" 7 | ; for this to work you also need to make sure that opc can find the technology files 8 | ; the easiest way to do this is to add the location to the config file at ~/.opcconfig.lua: 9 | ; please note that the path to the parent directory of the technology files, not the actual directory 10 | ; return { 11 | ; techpaths = { 12 | ; "/path/to/technology_files" 13 | ; } 14 | ; } 15 | 16 | ; the installation DIRECTORY of openPCells has to be given: 17 | OPCPath = "/path/to/opc" 18 | 19 | ; the name of the executable (which will be 'opc' if you don't change this manually during compiling) 20 | OPCExec = "opc" 21 | 22 | ; lastly, we load the opc interface for virtuoso 23 | load(lsprintf("%s/interface/virtuoso/init.il" OPCPath)) 24 | -------------------------------------------------------------------------------- /interface/virtuoso/init.il: -------------------------------------------------------------------------------- 1 | foreach(file list("backup" "call" "edit_update" "export" "menu" "misc" "settings" "subcell" "cells") 2 | load(lsprintf("%s/interface/virtuoso/%s.il" OPCPath file)) 3 | ) 4 | 5 | ; initialize forms 6 | unless(boundp('OPCSettingsForm) 7 | OPCCreateSettingsForm() 8 | ) 9 | -------------------------------------------------------------------------------- /interface/virtuoso/misc.il: -------------------------------------------------------------------------------- 1 | procedure(OPCAboutCallback() 2 | let( 3 | (OPCAboutForm) 4 | OPCAboutForm = hiCreateAppForm( 5 | ?name 'OPCAboutForm 6 | ?formTitle "openPCells About" 7 | ?buttonLayout 'OKCancel 8 | ?fields list( 9 | hiCreateHypertextField( 10 | ?name 'OPCHTMLField 11 | ?title "" 12 | ?value "

openPCells – A framework for open layout cell generators

openPCells (opc) 0.1.0 – ©Patrick Kurth 2020–2021

Website" 13 | ) 14 | ) 15 | ) 16 | hiDisplayForm(OPCAboutForm 100:100) 17 | ) 18 | ) ; procedure 19 | -------------------------------------------------------------------------------- /logo/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all 2 | all: 3 | lualatex logo.tex 4 | -------------------------------------------------------------------------------- /logo/logo.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickschulz/openPCells/14f34e0a04d0e87ac7ac1027ab7522b20e90d074/logo/logo.pdf -------------------------------------------------------------------------------- /logo/logo.tex: -------------------------------------------------------------------------------- 1 | \documentclass{standalone} 2 | 3 | \usepackage{tikz} 4 | \usepackage{fontspec} 5 | \setmainfont{Linux Libertine} 6 | 7 | \begin{document} 8 | \begin{tikzpicture} 9 | \def\radius{1} 10 | \def\angle{60} 11 | %\path[use as bounding box] ({-1 * \radius}, {sin(180 + \angle) * \radius}) rectangle ({1 * \radius}, {1 * \radius}); 12 | \begin{scope} 13 | \draw[clip] ({\radius * cos(180 + \angle)}, {\radius * sin(180 + \angle)}) arc[start angle = 180 + \angle, end angle = -\angle, radius = \radius] -- cycle; 14 | \draw[black!60] ({-2 * \radius}, {-2 * \radius}) grid[step = 1mm] ({2 * \radius}, {2 * \radius}); 15 | \draw ({\radius * cos(180 + \angle)}, {\radius * sin(180 + \angle)}) arc[start angle = 180 + \angle, end angle = -\angle, radius = \radius] -- cycle; 16 | \end{scope} 17 | \node[font = \Huge\bfseries] {OPC}; 18 | \node[anchor = north] at (0, {sin(180 + \angle) * \radius}) {openPCells}; 19 | \end{tikzpicture} 20 | \end{document} 21 | -------------------------------------------------------------------------------- /resources/extract_pinoffsets.lua: -------------------------------------------------------------------------------- 1 | local celllist = { 2 | "buf", 3 | "cinv", 4 | "not_gate", 5 | "nand_gate", 6 | "nor_gate", 7 | "or_gate", 8 | "and_gate", 9 | --"tbuf", 10 | "xor_gate", 11 | "dffpq", 12 | "dffnq", 13 | "dffprq", 14 | "dffnrq", 15 | "dffpsq", 16 | "dffnsq", 17 | --"dffprsq", 18 | --"dffnrsq", 19 | } 20 | 21 | local gatelength = 200 22 | local gatespace = 300 23 | local routingwidth = 200 24 | local routingspace = 300 25 | 26 | pcell.push_overwrites("stdcells/base", { 27 | glength = gatelength, 28 | gspace = gatespace, 29 | routingwidth = routingwidth, 30 | routingspace = routingspace, 31 | powerwidth = 480, 32 | pnumtracks = 3, 33 | nnumtracks = 3, 34 | }) 35 | 36 | local toplevel = object.create("opctoplevel") 37 | local lastanchor 38 | 39 | local lines = {} 40 | table.insert(lines, "return {") 41 | for i, cellname in ipairs(celllist) do 42 | local cell = pcell.create_layout(string.format("stdcells/%s", cellname), cellname) 43 | local child = toplevel:add_child(cell, cellname) 44 | child:move_anchor_y("bottom", lastanchor) 45 | lastanchor = child:get_anchor("top") 46 | 47 | local left = child:get_anchor("left") 48 | local right = child:get_anchor("right") 49 | local width = (right:getx() - left:getx()) / (gatelength + gatespace) 50 | table.insert(lines, string.format(" %s = {", cellname)) 51 | table.insert(lines, string.format(" width = %d,", width)) 52 | local ports = cell:get_ports() 53 | table.insert(lines, " pinoffsets = {") 54 | for _, port in ipairs(ports) do 55 | if port.name ~= "VDD" and port.name ~= "VSS" then 56 | local x, y = port.where:unwrap() 57 | local xoffset = x / (gatelength + gatespace) 58 | local yoffset = y / (routingwidth + routingspace) 59 | --table.insert(lines, string.format(" %s = { x = %d, y = %d },", port.name, math.floor(xoffset), math.floor(yoffset))) 60 | table.insert(lines, string.format(" %s = { x = %.1f, y = %.1f },", port.name, xoffset, yoffset)) 61 | end 62 | end 63 | table.insert(lines, " },") 64 | table.insert(lines, " },") 65 | end 66 | table.insert(lines, "}") 67 | print(table.concat(lines, "\n")) 68 | 69 | return toplevel 70 | -------------------------------------------------------------------------------- /resources/extract_stdcells_netlists.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | FILENAMES=$(ls ../cells/stdcells/*.lua) 4 | OUTPUTPATH="spice/stdcells" 5 | 6 | mkdir -p ../${OUTPUTPATH} 7 | for FILE in $FILENAMES 8 | do 9 | cellname=$(basename ${FILE%.lua}) 10 | (cd .. && 11 | echo stdcells/${cellname} 12 | ./opc --technology opc --export gds --cell stdcells/${cellname} && 13 | klayout openPCells.gds -rd filename=${cellname}.sp -z -nc -rx -n opc -r resources/opc.lylvs && 14 | sed -i "s/opctoplevel/${cellname}/" *.sp && 15 | mv *.sp $OUTPUTPATH 16 | ) 17 | done 18 | -------------------------------------------------------------------------------- /resources/stdcells_netlists/1_inv_gate.sp: -------------------------------------------------------------------------------- 1 | * Created by KLayout 2 | 3 | * cell 1_inv_gate 4 | * pin VSS 5 | * pin A 6 | * pin O 7 | * pin B 8 | * pin VDD 9 | * pin SUBSTRATE 10 | .SUBCKT 1_inv_gate VSS A O B VDD SUBSTRATE 11 | * device instance $1 r0 *1 0,1.2 slvtpfet 12 | M$1 VDD A \$6 \$9 slvtpfet L=0.2U W=1U AS=0.4P AD=0.15P PS=2.8U PD=1.3U 13 | * device instance $2 r0 *1 0.5,1.2 slvtpfet 14 | M$2 \$6 B VDD \$9 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 15 | * device instance $3 r0 *1 1,1.2 slvtpfet 16 | M$3 VDD VDD VDD \$9 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 17 | * device instance $4 r0 *1 1.5,1.2 slvtpfet 18 | M$4 VDD \$6 O \$9 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 19 | * device instance $5 r0 *1 2,1.2 slvtpfet 20 | M$5 O VDD VDD \$9 slvtpfet L=0.2U W=1U AS=0.15P AD=0.4P PS=1.3U PD=2.8U 21 | * device instance $6 r0 *1 0,-1.2 slvtnfet 22 | M$6 VSS A \$8 SUBSTRATE slvtnfet L=0.2U W=1U AS=0.4P AD=0.15P PS=2.8U PD=1.3U 23 | * device instance $7 r0 *1 0.5,-1.2 slvtnfet 24 | M$7 \$8 B \$6 SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 25 | * device instance $8 r0 *1 1,-1.2 slvtnfet 26 | M$8 \$6 VSS VSS SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 27 | * device instance $9 r0 *1 1.5,-1.2 slvtnfet 28 | M$9 VSS \$6 O SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 29 | * device instance $10 r0 *1 2,-1.2 slvtnfet 30 | M$10 O VSS VSS SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.4P PS=1.3U PD=2.8U 31 | .ENDS 1_inv_gate 32 | -------------------------------------------------------------------------------- /resources/stdcells_netlists/21_gate.sp: -------------------------------------------------------------------------------- 1 | * Created by KLayout 2 | 3 | * cell 21_gate 4 | * pin A 5 | * pin B1 6 | * pin B2 7 | * pin O 8 | * pin VDD 9 | * pin VSS 10 | * pin SUBSTRATE 11 | .SUBCKT 21_gate A B1 B2 O VDD VSS SUBSTRATE 12 | * device instance $1 r0 *1 0,1.2 slvtpfet 13 | M$1 VDD B1 \$1 \$I1 slvtpfet L=0.2U W=1U AS=0.4P AD=0.15P PS=2.8U PD=1.3U 14 | * device instance $2 r0 *1 0.5,1.2 slvtpfet 15 | M$2 \$1 B2 VDD \$I1 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 16 | * device instance $3 r0 *1 1,1.2 slvtpfet 17 | M$3 VDD VDD VDD \$I1 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 18 | * device instance $4 r0 *1 1.5,1.2 slvtpfet 19 | M$4 VDD A \$I14 \$I1 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 20 | * device instance $5 r0 *1 2,1.2 slvtpfet 21 | M$5 \$I14 \$1 O \$I1 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 22 | * device instance $6 r0 *1 2.5,1.2 slvtpfet 23 | M$6 O VDD VDD \$I1 slvtpfet L=0.2U W=1U AS=0.15P AD=0.4P PS=1.3U PD=2.8U 24 | * device instance $7 r0 *1 0,-1.2 slvtnfet 25 | M$7 VSS B1 \$I19 SUBSTRATE slvtnfet L=0.2U W=1U AS=0.4P AD=0.15P PS=2.8U PD=1.3U 26 | * device instance $8 r0 *1 0.5,-1.2 slvtnfet 27 | M$8 \$I19 B2 \$1 SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U 28 | + PD=1.3U 29 | * device instance $9 r0 *1 1,-1.2 slvtnfet 30 | M$9 \$1 VSS VSS SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 31 | * device instance $10 r0 *1 1.5,-1.2 slvtnfet 32 | M$10 VSS A O SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 33 | * device instance $11 r0 *1 2,-1.2 slvtnfet 34 | M$11 O \$1 VSS SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 35 | * device instance $12 r0 *1 2.5,-1.2 slvtnfet 36 | M$12 VSS VSS VSS SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.4P PS=1.3U PD=2.8U 37 | .ENDS 21_gate 38 | -------------------------------------------------------------------------------- /resources/stdcells_netlists/and_gate.sp: -------------------------------------------------------------------------------- 1 | * Created by KLayout 2 | 3 | * cell and_gate 4 | * pin VSS 5 | * pin A 6 | * pin O 7 | * pin B 8 | * pin VDD 9 | * pin SUBSTRATE 10 | .SUBCKT and_gate VSS A O B VDD SUBSTRATE 11 | * device instance $1 r0 *1 0,1.2 slvtpfet 12 | M$1 VDD A \$6 \$9 slvtpfet L=0.2U W=1U AS=0.4P AD=0.15P PS=2.8U PD=1.3U 13 | * device instance $2 r0 *1 0.5,1.2 slvtpfet 14 | M$2 \$6 B VDD \$9 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 15 | * device instance $3 r0 *1 1,1.2 slvtpfet 16 | M$3 VDD VDD VDD \$9 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 17 | * device instance $4 r0 *1 1.5,1.2 slvtpfet 18 | M$4 VDD \$6 O \$9 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 19 | * device instance $5 r0 *1 2,1.2 slvtpfet 20 | M$5 O VDD VDD \$9 slvtpfet L=0.2U W=1U AS=0.15P AD=0.4P PS=1.3U PD=2.8U 21 | * device instance $6 r0 *1 0,-1.2 slvtnfet 22 | M$6 VSS A \$8 SUBSTRATE slvtnfet L=0.2U W=1U AS=0.4P AD=0.15P PS=2.8U PD=1.3U 23 | * device instance $7 r0 *1 0.5,-1.2 slvtnfet 24 | M$7 \$8 B \$6 SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 25 | * device instance $8 r0 *1 1,-1.2 slvtnfet 26 | M$8 \$6 VSS VSS SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 27 | * device instance $9 r0 *1 1.5,-1.2 slvtnfet 28 | M$9 VSS \$6 O SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 29 | * device instance $10 r0 *1 2,-1.2 slvtnfet 30 | M$10 O VSS VSS SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.4P PS=1.3U PD=2.8U 31 | .ENDS and_gate 32 | -------------------------------------------------------------------------------- /resources/stdcells_netlists/buf.sp: -------------------------------------------------------------------------------- 1 | * Created by KLayout 2 | 3 | * cell buf 4 | * pin I 5 | * pin VSS 6 | * pin VDD 7 | * pin O 8 | * pin SUBSTRATE 9 | .SUBCKT buf I VSS VDD O SUBSTRATE 10 | * device instance $1 r0 *1 0,1.2 slvtpfet 11 | M$1 VDD I \$5 \$1 slvtpfet L=0.2U W=1U AS=0.4P AD=0.15P PS=2.8U PD=1.3U 12 | * device instance $2 r0 *1 0.5,1.2 slvtpfet 13 | M$2 \$5 VDD VDD \$1 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 14 | * device instance $3 r0 *1 1,1.2 slvtpfet 15 | M$3 VDD \$5 O \$1 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 16 | * device instance $4 r0 *1 1.5,1.2 slvtpfet 17 | M$4 O VDD VDD \$1 slvtpfet L=0.2U W=1U AS=0.15P AD=0.4P PS=1.3U PD=2.8U 18 | * device instance $5 r0 *1 0,-1.2 slvtnfet 19 | M$5 VSS I \$5 SUBSTRATE slvtnfet L=0.2U W=1U AS=0.4P AD=0.15P PS=2.8U PD=1.3U 20 | * device instance $6 r0 *1 0.5,-1.2 slvtnfet 21 | M$6 \$5 VSS VSS SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 22 | * device instance $7 r0 *1 1,-1.2 slvtnfet 23 | M$7 VSS \$5 O SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 24 | * device instance $8 r0 *1 1.5,-1.2 slvtnfet 25 | M$8 O VSS VSS SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.4P PS=1.3U PD=2.8U 26 | .ENDS buf 27 | -------------------------------------------------------------------------------- /resources/stdcells_netlists/cinv.sp: -------------------------------------------------------------------------------- 1 | * Created by KLayout 2 | 3 | * cell cinv 4 | * pin I 5 | * pin EN 6 | * pin EP 7 | * pin VDD 8 | * pin VSS 9 | * pin SUBSTRATE 10 | .SUBCKT cinv I EN EP VDD VSS SUBSTRATE 11 | * device instance $1 r0 *1 0,1.2 slvtpfet 12 | M$1 \$5 I \$13 \$1 slvtpfet L=0.2U W=1U AS=0.4P AD=0.15P PS=2.8U PD=1.3U 13 | * device instance $2 r0 *1 0.5,1.2 slvtpfet 14 | M$2 \$13 EP VDD \$1 slvtpfet L=0.2U W=1U AS=0.15P AD=0.4P PS=1.3U PD=2.8U 15 | * device instance $3 r0 *1 0,-1.2 slvtnfet 16 | M$3 \$5 I \$14 SUBSTRATE slvtnfet L=0.2U W=1U AS=0.4P AD=0.15P PS=2.8U PD=1.3U 17 | * device instance $4 r0 *1 0.5,-1.2 slvtnfet 18 | M$4 \$14 EN VSS SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.4P PS=1.3U PD=2.8U 19 | .ENDS cinv 20 | -------------------------------------------------------------------------------- /resources/stdcells_netlists/colstop.sp: -------------------------------------------------------------------------------- 1 | * Created by KLayout 2 | 3 | * cell colstop 4 | * pin SUBSTRATE 5 | .SUBCKT colstop SUBSTRATE 6 | * device instance $1 r0 *1 0,1.2 slvtpfet 7 | M$1 \$2 \$2 \$7 \$4 slvtpfet L=0.2U W=1U AS=0.15P AD=0.4P PS=1.3U PD=2.8U 8 | * device instance $2 r0 *1 0,-1.2 slvtnfet 9 | M$2 \$1 \$1 \$8 SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.4P PS=1.3U PD=2.8U 10 | .ENDS colstop 11 | -------------------------------------------------------------------------------- /resources/stdcells_netlists/endcell.sp: -------------------------------------------------------------------------------- 1 | * Created by KLayout 2 | -------------------------------------------------------------------------------- /resources/stdcells_netlists/generic2bit.sp: -------------------------------------------------------------------------------- 1 | * Created by KLayout 2 | -------------------------------------------------------------------------------- /resources/stdcells_netlists/harness.sp: -------------------------------------------------------------------------------- 1 | * Created by KLayout 2 | 3 | * cell harness 4 | * pin SUBSTRATE 5 | .SUBCKT harness SUBSTRATE 6 | * device instance $1 r0 *1 0,1.2 slvtpfet 7 | M$1 \$8 \$1 \$7 \$2 slvtpfet L=0.2U W=1U AS=0.4P AD=0.4P PS=2.8U PD=2.8U 8 | * device instance $2 r0 *1 0,-1.2 slvtnfet 9 | M$2 \$10 \$1 \$9 SUBSTRATE slvtnfet L=0.2U W=1U AS=0.4P AD=0.4P PS=2.8U PD=2.8U 10 | .ENDS harness 11 | -------------------------------------------------------------------------------- /resources/stdcells_netlists/isogate.sp: -------------------------------------------------------------------------------- 1 | * Created by KLayout 2 | 3 | * cell isogate 4 | * pin SUBSTRATE 5 | .SUBCKT isogate SUBSTRATE 6 | * device instance $1 r0 *1 0.25,1.2 slvtpfet 7 | M$1 \$5 \$2 \$4 \$3 slvtpfet L=0.2U W=1U AS=0.4P AD=0.4P PS=2.8U PD=2.8U 8 | * device instance $2 r0 *1 0.25,-1.2 slvtnfet 9 | M$2 \$7 \$1 \$6 SUBSTRATE slvtnfet L=0.2U W=1U AS=0.4P AD=0.4P PS=2.8U PD=2.8U 10 | .ENDS isogate 11 | -------------------------------------------------------------------------------- /resources/stdcells_netlists/latch_cell.sp: -------------------------------------------------------------------------------- 1 | * Created by KLayout 2 | 3 | * cell latch_cell 4 | * pin SUBSTRATE 5 | .SUBCKT latch_cell SUBSTRATE 6 | * device instance $1 r0 *1 0,1.2 slvtpfet 7 | M$1 \$9 \$2 \$2 \$1 slvtpfet L=0.2U W=1U AS=0.4P AD=0.15P PS=2.8U PD=1.3U 8 | * device instance $2 r0 *1 0.5,1.2 slvtpfet 9 | M$2 \$2 \$3 \$10 \$1 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 10 | * device instance $3 r0 *1 1,1.2 slvtpfet 11 | M$3 \$10 \$4 \$10 \$1 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 12 | * device instance $4 r0 *1 1.5,1.2 slvtpfet 13 | M$4 \$10 \$5 \$8 \$1 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 14 | * device instance $5 r0 *1 2,1.2 slvtpfet 15 | M$5 \$8 \$6 \$22 \$1 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 16 | * device instance $6 r0 *1 2.5,1.2 slvtpfet 17 | M$6 \$22 \$8 \$21 \$1 slvtpfet L=0.2U W=1U AS=0.15P AD=0.4P PS=1.3U PD=2.8U 18 | * device instance $7 r0 *1 0,-1.2 slvtnfet 19 | M$7 \$9 \$2 \$2 SUBSTRATE slvtnfet L=0.2U W=1U AS=0.4P AD=0.15P PS=2.8U PD=1.3U 20 | * device instance $8 r0 *1 0.5,-1.2 slvtnfet 21 | M$8 \$2 \$3 \$24 SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U 22 | + PD=1.3U 23 | * device instance $9 r0 *1 1,-1.2 slvtnfet 24 | M$9 \$24 \$4 \$7 SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U 25 | + PD=1.3U 26 | * device instance $10 r0 *1 1.5,-1.2 slvtnfet 27 | M$10 \$7 \$5 \$7 SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U 28 | + PD=1.3U 29 | * device instance $11 r0 *1 2,-1.2 slvtnfet 30 | M$11 \$7 \$6 \$23 SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U 31 | + PD=1.3U 32 | * device instance $12 r0 *1 2.5,-1.2 slvtnfet 33 | M$12 \$23 \$7 \$25 SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.4P PS=1.3U 34 | + PD=2.8U 35 | .ENDS latch_cell 36 | -------------------------------------------------------------------------------- /resources/stdcells_netlists/leftcolstop.sp: -------------------------------------------------------------------------------- 1 | * Created by KLayout 2 | 3 | * cell leftcolstop 4 | * pin SUBSTRATE 5 | .SUBCKT leftcolstop SUBSTRATE 6 | * device instance $1 r0 *1 0,1.2 slvtpfet 7 | M$1 \$2 \$2 \$7 \$4 slvtpfet L=0.2U W=1U AS=0.15P AD=0.4P PS=1.3U PD=2.8U 8 | * device instance $2 r0 *1 0,-1.2 slvtnfet 9 | M$2 \$1 \$1 \$8 SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.4P PS=1.3U PD=2.8U 10 | .ENDS leftcolstop 11 | -------------------------------------------------------------------------------- /resources/stdcells_netlists/mux.sp: -------------------------------------------------------------------------------- 1 | * Created by KLayout 2 | 3 | * cell mux 4 | * pin A,B 5 | * pin O 6 | * pin VDD 7 | * pin VSS 8 | * pin SUBSTRATE 9 | .SUBCKT mux A|B O VDD VSS SUBSTRATE 10 | * device instance $1 r0 *1 0,1.2 slvtpfet 11 | M$1 VDD A|B \$7 \$1 slvtpfet L=0.2U W=1U AS=0.4P AD=0.15P PS=2.8U PD=1.3U 12 | * device instance $2 r0 *1 0.5,1.2 slvtpfet 13 | M$2 \$7 \$3 \$9 \$1 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 14 | * device instance $3 r0 *1 1,1.2 slvtpfet 15 | M$3 \$9 O VDD \$1 slvtpfet L=0.2U W=1U AS=0.15P AD=0.4P PS=1.3U PD=2.8U 16 | * device instance $4 r0 *1 0,-1.2 slvtnfet 17 | M$4 VSS A|B \$8 SUBSTRATE slvtnfet L=0.2U W=1U AS=0.4P AD=0.15P PS=2.8U PD=1.3U 18 | * device instance $5 r0 *1 0.5,-1.2 slvtnfet 19 | M$5 \$8 \$3 \$10 SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U 20 | + PD=1.3U 21 | * device instance $6 r0 *1 1,-1.2 slvtnfet 22 | M$6 \$10 O VSS SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.4P PS=1.3U PD=2.8U 23 | .ENDS mux 24 | -------------------------------------------------------------------------------- /resources/stdcells_netlists/nand_gate.sp: -------------------------------------------------------------------------------- 1 | * Created by KLayout 2 | 3 | * cell nand_gate 4 | * pin A 5 | * pin B 6 | * pin VSS 7 | * pin VDD 8 | * pin O 9 | * pin SUBSTRATE 10 | .SUBCKT nand_gate A B VSS VDD O SUBSTRATE 11 | * device instance $1 r0 *1 0,1.2 slvtpfet 12 | M$1 VDD A O \$1 slvtpfet L=0.2U W=1U AS=0.4P AD=0.15P PS=2.8U PD=1.3U 13 | * device instance $2 r0 *1 0.5,1.2 slvtpfet 14 | M$2 O B VDD \$1 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 15 | * device instance $3 r0 *1 1,1.2 slvtpfet 16 | M$3 VDD VDD VDD \$1 slvtpfet L=0.2U W=1U AS=0.15P AD=0.4P PS=1.3U PD=2.8U 17 | * device instance $4 r0 *1 0,-1.2 slvtnfet 18 | M$4 VSS A \$11 SUBSTRATE slvtnfet L=0.2U W=1U AS=0.4P AD=0.15P PS=2.8U PD=1.3U 19 | * device instance $5 r0 *1 0.5,-1.2 slvtnfet 20 | M$5 \$11 B O SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 21 | * device instance $6 r0 *1 1,-1.2 slvtnfet 22 | M$6 O VSS VSS SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.4P PS=1.3U PD=2.8U 23 | .ENDS nand_gate 24 | -------------------------------------------------------------------------------- /resources/stdcells_netlists/nand_nor_layout_base.sp: -------------------------------------------------------------------------------- 1 | * Created by KLayout 2 | 3 | * cell nand_nor_layout_base 4 | * pin A 5 | * pin B 6 | * pin VSS 7 | * pin VDD 8 | * pin O 9 | * pin SUBSTRATE 10 | .SUBCKT nand_nor_layout_base A B VSS VDD O SUBSTRATE 11 | * device instance $1 r0 *1 0,1.2 slvtpfet 12 | M$1 VDD A O \$1 slvtpfet L=0.2U W=1U AS=0.4P AD=0.15P PS=2.8U PD=1.3U 13 | * device instance $2 r0 *1 0.5,1.2 slvtpfet 14 | M$2 O B VDD \$1 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 15 | * device instance $3 r0 *1 1,1.2 slvtpfet 16 | M$3 VDD VDD VDD \$1 slvtpfet L=0.2U W=1U AS=0.15P AD=0.4P PS=1.3U PD=2.8U 17 | * device instance $4 r0 *1 0,-1.2 slvtnfet 18 | M$4 VSS A \$11 SUBSTRATE slvtnfet L=0.2U W=1U AS=0.4P AD=0.15P PS=2.8U PD=1.3U 19 | * device instance $5 r0 *1 0.5,-1.2 slvtnfet 20 | M$5 \$11 B O SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 21 | * device instance $6 r0 *1 1,-1.2 slvtnfet 22 | M$6 O VSS VSS SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.4P PS=1.3U PD=2.8U 23 | .ENDS nand_nor_layout_base 24 | -------------------------------------------------------------------------------- /resources/stdcells_netlists/nor_gate.sp: -------------------------------------------------------------------------------- 1 | * Created by KLayout 2 | 3 | * cell nor_gate 4 | * pin A 5 | * pin B 6 | * pin VSS 7 | * pin VDD 8 | * pin O 9 | * pin SUBSTRATE 10 | .SUBCKT nor_gate A B VSS VDD O SUBSTRATE 11 | * device instance $1 r0 *1 0,1.2 slvtpfet 12 | M$1 VDD A \$11 \$1 slvtpfet L=0.2U W=1U AS=0.4P AD=0.15P PS=2.8U PD=1.3U 13 | * device instance $2 r0 *1 0.5,1.2 slvtpfet 14 | M$2 \$11 B O \$1 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 15 | * device instance $3 r0 *1 1,1.2 slvtpfet 16 | M$3 O VDD VDD \$1 slvtpfet L=0.2U W=1U AS=0.15P AD=0.4P PS=1.3U PD=2.8U 17 | * device instance $4 r0 *1 0,-1.2 slvtnfet 18 | M$4 VSS A O SUBSTRATE slvtnfet L=0.2U W=1U AS=0.4P AD=0.15P PS=2.8U PD=1.3U 19 | * device instance $5 r0 *1 0.5,-1.2 slvtnfet 20 | M$5 O B VSS SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 21 | * device instance $6 r0 *1 1,-1.2 slvtnfet 22 | M$6 VSS VSS VSS SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.4P PS=1.3U PD=2.8U 23 | .ENDS nor_gate 24 | -------------------------------------------------------------------------------- /resources/stdcells_netlists/not_gate.sp: -------------------------------------------------------------------------------- 1 | * Created by KLayout 2 | 3 | * cell not_gate 4 | * pin I 5 | * pin VSS 6 | * pin VDD 7 | * pin O 8 | * pin SUBSTRATE 9 | .SUBCKT not_gate I VSS VDD O SUBSTRATE 10 | * device instance $1 r0 *1 0,1.2 slvtpfet 11 | M$1 VDD I O \$1 slvtpfet L=0.2U W=1U AS=0.4P AD=0.15P PS=2.8U PD=1.3U 12 | * device instance $2 r0 *1 0.5,1.2 slvtpfet 13 | M$2 O VDD VDD \$1 slvtpfet L=0.2U W=1U AS=0.15P AD=0.4P PS=1.3U PD=2.8U 14 | * device instance $3 r0 *1 0,-1.2 slvtnfet 15 | M$3 VSS I O SUBSTRATE slvtnfet L=0.2U W=1U AS=0.4P AD=0.15P PS=2.8U PD=1.3U 16 | * device instance $4 r0 *1 0.5,-1.2 slvtnfet 17 | M$4 O VSS VSS SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.4P PS=1.3U PD=2.8U 18 | .ENDS not_gate 19 | -------------------------------------------------------------------------------- /resources/stdcells_netlists/or_gate.sp: -------------------------------------------------------------------------------- 1 | * Created by KLayout 2 | 3 | * cell or_gate 4 | * pin VSS 5 | * pin A 6 | * pin O 7 | * pin B 8 | * pin VDD 9 | * pin SUBSTRATE 10 | .SUBCKT or_gate VSS A O B VDD SUBSTRATE 11 | * device instance $1 r0 *1 0,1.2 slvtpfet 12 | M$1 VDD A \$12 \$6 slvtpfet L=0.2U W=1U AS=0.4P AD=0.15P PS=2.8U PD=1.3U 13 | * device instance $2 r0 *1 0.5,1.2 slvtpfet 14 | M$2 \$12 B \$7 \$6 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 15 | * device instance $3 r0 *1 1,1.2 slvtpfet 16 | M$3 \$7 VDD VDD \$6 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 17 | * device instance $4 r0 *1 1.5,1.2 slvtpfet 18 | M$4 VDD \$7 O \$6 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 19 | * device instance $5 r0 *1 2,1.2 slvtpfet 20 | M$5 O VDD VDD \$6 slvtpfet L=0.2U W=1U AS=0.15P AD=0.4P PS=1.3U PD=2.8U 21 | * device instance $6 r0 *1 0,-1.2 slvtnfet 22 | M$6 VSS A \$7 SUBSTRATE slvtnfet L=0.2U W=1U AS=0.4P AD=0.15P PS=2.8U PD=1.3U 23 | * device instance $7 r0 *1 0.5,-1.2 slvtnfet 24 | M$7 \$7 B VSS SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 25 | * device instance $8 r0 *1 1,-1.2 slvtnfet 26 | M$8 VSS VSS VSS SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 27 | * device instance $9 r0 *1 1.5,-1.2 slvtnfet 28 | M$9 VSS \$7 O SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 29 | * device instance $10 r0 *1 2,-1.2 slvtnfet 30 | M$10 O VSS VSS SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.4P PS=1.3U PD=2.8U 31 | .ENDS or_gate 32 | -------------------------------------------------------------------------------- /resources/stdcells_netlists/rightcolstop.sp: -------------------------------------------------------------------------------- 1 | * Created by KLayout 2 | 3 | * cell rightcolstop 4 | * pin SUBSTRATE 5 | .SUBCKT rightcolstop SUBSTRATE 6 | * device instance $1 r0 *1 0,1.2 slvtpfet 7 | M$1 \$7 \$2 \$2 \$4 slvtpfet L=0.2U W=1U AS=0.4P AD=0.15P PS=2.8U PD=1.3U 8 | * device instance $2 r0 *1 0,-1.2 slvtnfet 9 | M$2 \$8 \$1 \$1 SUBSTRATE slvtnfet L=0.2U W=1U AS=0.4P AD=0.15P PS=2.8U PD=1.3U 10 | .ENDS rightcolstop 11 | -------------------------------------------------------------------------------- /resources/stdcells_netlists/tbuf.sp: -------------------------------------------------------------------------------- 1 | * Created by KLayout 2 | 3 | * cell tbuf 4 | * pin VSS 5 | * pin EN 6 | * pin I 7 | * pin VDD 8 | * pin SUBSTRATE 9 | .SUBCKT tbuf VSS EN I VDD SUBSTRATE 10 | * device instance $1 r0 *1 0,1.2 slvtpfet 11 | M$1 VDD EN \$6 \$10 slvtpfet L=0.2U W=1U AS=0.4P AD=0.15P PS=2.8U PD=1.3U 12 | * device instance $2 r0 *1 0.5,1.2 slvtpfet 13 | M$2 \$6 VDD VDD \$10 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 14 | * device instance $3 r0 *1 1,1.2 slvtpfet 15 | M$3 VDD VDD \$7 \$10 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 16 | * device instance $4 r0 *1 1.5,1.2 slvtpfet 17 | M$4 \$7 I \$13 \$10 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 18 | * device instance $5 r0 *1 2,1.2 slvtpfet 19 | M$5 \$13 \$6 VDD \$10 slvtpfet L=0.2U W=1U AS=0.15P AD=0.4P PS=1.3U PD=2.8U 20 | * device instance $6 r0 *1 0,-1.2 slvtnfet 21 | M$6 VSS EN \$6 SUBSTRATE slvtnfet L=0.2U W=1U AS=0.4P AD=0.15P PS=2.8U PD=1.3U 22 | * device instance $7 r0 *1 0.5,-1.2 slvtnfet 23 | M$7 \$6 VSS VSS SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 24 | * device instance $8 r0 *1 1,-1.2 slvtnfet 25 | M$8 VSS VSS \$7 SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 26 | * device instance $9 r0 *1 1.5,-1.2 slvtnfet 27 | M$9 \$7 I \$8 SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 28 | * device instance $10 r0 *1 2,-1.2 slvtnfet 29 | M$10 \$8 EN VSS SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.4P PS=1.3U PD=2.8U 30 | .ENDS tbuf 31 | -------------------------------------------------------------------------------- /resources/stdcells_netlists/tgate.sp: -------------------------------------------------------------------------------- 1 | * Created by KLayout 2 | 3 | * cell tgate 4 | * pin EN 5 | * pin EP 6 | * pin I 7 | * pin O 8 | * pin SUBSTRATE 9 | .SUBCKT tgate EN EP I O SUBSTRATE 10 | * device instance $1 r0 *1 0,1.2 slvtpfet 11 | M$1 I EP O \$7 slvtpfet L=0.2U W=1U AS=0.4P AD=0.4P PS=2.8U PD=2.8U 12 | * device instance $2 r0 *1 0,-1.2 slvtnfet 13 | M$2 I EN O SUBSTRATE slvtnfet L=0.2U W=1U AS=0.4P AD=0.4P PS=2.8U PD=2.8U 14 | .ENDS tgate 15 | -------------------------------------------------------------------------------- /resources/stdcells_netlists/xnor_gate.sp: -------------------------------------------------------------------------------- 1 | * Created by KLayout 2 | 3 | * cell xnor_gate 4 | * pin VSS 5 | * pin A,B,O 6 | * pin VDD 7 | * pin SUBSTRATE 8 | .SUBCKT xnor_gate VSS A|B|O VDD SUBSTRATE 9 | * device instance $1 r0 *1 -1,1.2 slvtpfet 10 | M$1 VDD A|B|O A|B|O \$14 slvtpfet L=0.2U W=2U AS=0.55P AD=0.3P PS=4.1U PD=2.6U 11 | * device instance $2 r0 *1 -0.5,1.2 slvtpfet 12 | M$2 A|B|O VDD VDD \$14 slvtpfet L=0.2U W=2U AS=0.3P AD=0.3P PS=2.6U PD=2.6U 13 | * device instance $5 r0 *1 1,1.2 slvtpfet 14 | M$5 VDD A|B|O \$16 \$14 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 15 | * device instance $6 r0 *1 1.5,1.2 slvtpfet 16 | M$6 \$16 A|B|O \$16 \$14 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 17 | * device instance $7 r0 *1 2,1.2 slvtpfet 18 | M$7 \$16 A|B|O \$12 \$14 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 19 | * device instance $8 r0 *1 2.5,1.2 slvtpfet 20 | M$8 \$12 A|B|O \$22 \$14 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 21 | * device instance $9 r0 *1 3,1.2 slvtpfet 22 | M$9 \$22 A|B|O VDD \$14 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 23 | * device instance $10 r0 *1 3.5,1.2 slvtpfet 24 | M$10 VDD A|B|O VDD \$14 slvtpfet L=0.2U W=1U AS=0.15P AD=0.4P PS=1.3U PD=2.8U 25 | * device instance $11 r0 *1 -1,-1.2 slvtnfet 26 | M$11 VSS A|B|O A|B|O SUBSTRATE slvtnfet L=0.2U W=2U AS=0.55P AD=0.3P PS=4.1U 27 | + PD=2.6U 28 | * device instance $12 r0 *1 -0.5,-1.2 slvtnfet 29 | M$12 A|B|O VSS VSS SUBSTRATE slvtnfet L=0.2U W=2U AS=0.3P AD=0.3P PS=2.6U 30 | + PD=2.6U 31 | * device instance $15 r0 *1 1,-1.2 slvtnfet 32 | M$15 VSS A|B|O VSS SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U 33 | + PD=1.3U 34 | * device instance $16 r0 *1 1.5,-1.2 slvtnfet 35 | M$16 VSS A|B|O \$13 SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U 36 | + PD=1.3U 37 | * device instance $17 r0 *1 2,-1.2 slvtnfet 38 | M$17 \$13 A|B|O \$12 SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U 39 | + PD=1.3U 40 | * device instance $18 r0 *1 2.5,-1.2 slvtnfet 41 | M$18 \$12 A|B|O \$10 SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U 42 | + PD=1.3U 43 | * device instance $19 r0 *1 3,-1.2 slvtnfet 44 | M$19 \$10 A|B|O \$10 SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U 45 | + PD=1.3U 46 | * device instance $20 r0 *1 3.5,-1.2 slvtnfet 47 | M$20 \$10 A|B|O VSS SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.4P PS=1.3U 48 | + PD=2.8U 49 | .ENDS xnor_gate 50 | -------------------------------------------------------------------------------- /resources/stdcells_netlists/xor_gate.sp: -------------------------------------------------------------------------------- 1 | * Created by KLayout 2 | 3 | * cell xor_gate 4 | * pin VSS 5 | * pin A,B,O 6 | * pin VDD 7 | * pin SUBSTRATE 8 | .SUBCKT xor_gate VSS A|B|O VDD SUBSTRATE 9 | * device instance $1 r0 *1 0,1.2 slvtpfet 10 | M$1 VDD A|B|O A|B|O \$14 slvtpfet L=0.2U W=2U AS=0.55P AD=0.3P PS=4.1U PD=2.6U 11 | * device instance $2 r0 *1 0.5,1.2 slvtpfet 12 | M$2 A|B|O VDD VDD \$14 slvtpfet L=0.2U W=2U AS=0.3P AD=0.3P PS=2.6U PD=2.6U 13 | * device instance $5 r0 *1 2,1.2 slvtpfet 14 | M$5 VDD A|B|O \$16 \$14 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 15 | * device instance $6 r0 *1 2.5,1.2 slvtpfet 16 | M$6 \$16 A|B|O \$16 \$14 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 17 | * device instance $7 r0 *1 3,1.2 slvtpfet 18 | M$7 \$16 A|B|O \$12 \$14 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 19 | * device instance $8 r0 *1 3.5,1.2 slvtpfet 20 | M$8 \$12 A|B|O \$22 \$14 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 21 | * device instance $9 r0 *1 4,1.2 slvtpfet 22 | M$9 \$22 A|B|O VDD \$14 slvtpfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U PD=1.3U 23 | * device instance $10 r0 *1 4.5,1.2 slvtpfet 24 | M$10 VDD A|B|O VDD \$14 slvtpfet L=0.2U W=1U AS=0.15P AD=0.4P PS=1.3U PD=2.8U 25 | * device instance $11 r0 *1 0,-1.2 slvtnfet 26 | M$11 VSS A|B|O A|B|O SUBSTRATE slvtnfet L=0.2U W=2U AS=0.55P AD=0.3P PS=4.1U 27 | + PD=2.6U 28 | * device instance $12 r0 *1 0.5,-1.2 slvtnfet 29 | M$12 A|B|O VSS VSS SUBSTRATE slvtnfet L=0.2U W=2U AS=0.3P AD=0.3P PS=2.6U 30 | + PD=2.6U 31 | * device instance $15 r0 *1 2,-1.2 slvtnfet 32 | M$15 VSS A|B|O VSS SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U 33 | + PD=1.3U 34 | * device instance $16 r0 *1 2.5,-1.2 slvtnfet 35 | M$16 VSS A|B|O \$13 SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U 36 | + PD=1.3U 37 | * device instance $17 r0 *1 3,-1.2 slvtnfet 38 | M$17 \$13 A|B|O \$12 SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U 39 | + PD=1.3U 40 | * device instance $18 r0 *1 3.5,-1.2 slvtnfet 41 | M$18 \$12 A|B|O \$10 SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U 42 | + PD=1.3U 43 | * device instance $19 r0 *1 4,-1.2 slvtnfet 44 | M$19 \$10 A|B|O \$10 SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.15P PS=1.3U 45 | + PD=1.3U 46 | * device instance $20 r0 *1 4.5,-1.2 slvtnfet 47 | M$20 \$10 A|B|O VSS SUBSTRATE slvtnfet L=0.2U W=1U AS=0.15P AD=0.4P PS=1.3U 48 | + PD=2.8U 49 | .ENDS xor_gate 50 | -------------------------------------------------------------------------------- /saradc/caparray.lua: -------------------------------------------------------------------------------- 1 | local cell = object.create("toplevel") 2 | 3 | -- basic mos parameters 4 | local gatelength = 20 5 | local gatespace = 84 6 | local fingerwidth = 500 7 | local nfetvthtype = 1 8 | local pfetvthtype = 3 9 | local sdwidth = 40 10 | local sdspace = 80 11 | local powerwidth = 3 * sdwidth 12 | local powerspace = 3 * sdspace 13 | 14 | -- switch_network parameters 15 | local buffingers = 2 16 | local switchfingers = 8 17 | 18 | -- buf_array parameters 19 | local buff1ingers = 4 20 | local buff2ingers = 2 21 | 22 | -- cap_array parameters 23 | local bits = 8 24 | local rwidth = 100 25 | 26 | -- cap array up 27 | local cap_array_up = pcell.create_layout("SAR_ADC/cap_array", "cap_array_up", { 28 | bits = bits, 29 | rwidth = rwidth 30 | }) 31 | cell:merge_into(cap_array_up) 32 | 33 | return cell 34 | -------------------------------------------------------------------------------- /saradc/sample_and_hold.lua: -------------------------------------------------------------------------------- 1 | local cell = object.create("toplevel") 2 | 3 | local buffingers = 2 4 | local gatelength = 20 5 | local gatespace = 84 6 | local fingerwidth = 500 7 | local nfetvthtype = 1 8 | local pfetvthtype = 3 9 | local sdwidth = 40 10 | local sdspace = 80 11 | 12 | pcell.push_overwrites("basic/mosfet", { actext = 100 }) 13 | 14 | local sample_and_hold = pcell.create_layout("SAR_ADC/sample_and_hold", "sample_and_hold", { 15 | buffingers = buffingers, 16 | gatelength = gatelength, 17 | gatespace = gatespace, 18 | fingerwidth = fingerwidth, 19 | nfetvthtype = nfetvthtype, 20 | pfetvthtype = pfetvthtype, 21 | sdwidth = sdwidth, 22 | sdspace = sdspace, 23 | gstrwidth = sdwidth, 24 | gstrspace = sdspace, 25 | powerwidth = 3 * sdwidth, 26 | powerspace = 3 * sdspace 27 | 28 | }) 29 | cell:merge_into(sample_and_hold) 30 | 31 | pcell.pop_overwrites("basic/mosfet") 32 | 33 | return sample_and_hold 34 | -------------------------------------------------------------------------------- /saradc/switch_network_up.lua: -------------------------------------------------------------------------------- 1 | local cell = object.create("toplevel") 2 | 3 | local buffingers = 2 4 | local switchfingers = 8 5 | local gatelength = 20 6 | local gatespace = 84 7 | local fingerwidth = 500 8 | local nfetvthtype = 1 9 | local pfetvthtype = 3 10 | local sdwidth = 40 11 | local sdspace = 80 12 | 13 | 14 | local swup7 = pcell.create_layout("SAR_ADC/switch_network_up", "swup7", { 15 | buffingers = buffingers, 16 | switchfingers = switchfingers, 17 | gatelength = gatelength, 18 | gatespace = gatespace, 19 | fingerwidth = fingerwidth, 20 | nfetvthtype = nfetvthtype, 21 | pfetvthtype = pfetvthtype, 22 | sdwidth = sdwidth, 23 | sdspace = sdspace, 24 | gstrwidth = sdwidth, 25 | gstrspace = sdspace, 26 | powerwidth = 3 * sdwidth, 27 | powerspace = 3 * sdspace 28 | }) 29 | 30 | cell:merge_into_shallow(swup7:flatten()) 31 | 32 | --[[ 33 | 34 | cell:add_port("VDD", generics.metalport(1), swup7:get_anchor("VDD")) 35 | cell:add_port("VSS", generics.metalport(1), swup7:get_anchor("VSS")) 36 | cell:add_port("sample", generics.metalport(1), swup7:get_anchor("sample")) 37 | cell:add_port("vin", generics.metalport(2), swup7:get_anchor("vin")) 38 | cell:add_port("vout", generics.metalport(3), swup7:get_anchor("vout")) 39 | cell:add_port("data", generics.metalport(1), swup7:get_anchor("data")) 40 | cell:add_port("REF", generics.metalport(1), swup7:get_anchor("REF")) 41 | cell:add_port("GND", generics.metalport(1), swup7:get_anchor("GND")) 42 | cell:add_port("VSS", generics.otherport("nwell"), point.create(0, -1500)) 43 | 44 | 45 | --]] 46 | 47 | 48 | return swup7 49 | 50 | -------------------------------------------------------------------------------- /src/bltrshape.c: -------------------------------------------------------------------------------- 1 | #include "bltrshape.h" 2 | 3 | #include 4 | 5 | struct bltrshape { 6 | struct point* bl; 7 | struct point* tr; 8 | }; 9 | 10 | struct bltrshape* bltrshape_create(const struct point* bl, const struct point* tr) 11 | { 12 | struct bltrshape* bltrshape = malloc(sizeof(*bltrshape)); 13 | bltrshape->bl = point_copy(bl); 14 | bltrshape->tr = point_copy(tr); 15 | return bltrshape; 16 | } 17 | 18 | void bltrshape_destroy(void* v) 19 | { 20 | struct bltrshape* bltrshape = v; 21 | point_destroy(bltrshape->bl); 22 | point_destroy(bltrshape->tr); 23 | free(bltrshape); 24 | } 25 | 26 | /* const void* v because it is used as copy constructor */ 27 | void* bltrshape_copy(const void* v) 28 | { 29 | const struct bltrshape* bltrshape = v; 30 | return bltrshape_create(bltrshape->bl, bltrshape->tr); 31 | } 32 | 33 | const struct point* bltrshape_get_bl(const struct bltrshape* bltrshape) 34 | { 35 | return bltrshape->bl; 36 | } 37 | 38 | const struct point* bltrshape_get_tr(const struct bltrshape* bltrshape) 39 | { 40 | return bltrshape->tr; 41 | } 42 | -------------------------------------------------------------------------------- /src/bltrshape.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_BLTRSHAPE_H 2 | #define OPC_BLTRSHAPE_H 3 | 4 | #include "point.h" 5 | 6 | struct bltrshape; 7 | 8 | struct bltrshape* bltrshape_create(const struct point* bl, const struct point* tr); 9 | void bltrshape_destroy(void* v); 10 | void* bltrshape_copy(const void* v); /* const void* v because it is used as copy constructor */ 11 | const struct point* bltrshape_get_bl(const struct bltrshape* bltrshape); 12 | const struct point* bltrshape_get_tr(const struct bltrshape* bltrshape); 13 | 14 | #endif /* OPC_BLTRSHAPE_H */ 15 | -------------------------------------------------------------------------------- /src/cells.c: -------------------------------------------------------------------------------- 1 | #include "pcell.h" 2 | #include "technology.h" 3 | #include "geometry.h" 4 | 5 | #include "cells/powergrid.c" 6 | -------------------------------------------------------------------------------- /src/cells.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_CELLS_H 2 | #define OPC_CELLS_H 3 | 4 | #include "pcell.h" 5 | #include "technology.h" 6 | 7 | int cell_powergrid_layout(struct pcell_state* pcell_state, struct technology_state* techstate, struct object* powergrid); 8 | 9 | #endif /* OPC_CELLS_H */ 10 | -------------------------------------------------------------------------------- /src/cells/powergrid.c: -------------------------------------------------------------------------------- 1 | int cell_powergrid_layout(struct object* powergrid, struct technology_state* techstate, struct pcell_state* pcell_state) 2 | { 3 | (void)pcell_state; 4 | geometry_rectanglebltrxy( 5 | powergrid, 6 | generics_create_metal(techstate, 1), 7 | 0, 0, 8 | 100, 100 9 | ); 10 | return 1; 11 | } 12 | -------------------------------------------------------------------------------- /src/cpu.c: -------------------------------------------------------------------------------- 1 | #include "cpu.h" 2 | 3 | #include 4 | 5 | unsigned int cpu_get_num_cpus() 6 | { 7 | return (unsigned int)sysconf(_SC_NPROCESSORS_CONF); 8 | } 9 | 10 | -------------------------------------------------------------------------------- /src/cpu.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_CPU_H 2 | #define OPC_CPU_H 3 | 4 | /* returns the number of cpus on this machine, at least 1 */ 5 | unsigned int cpu_get_num_cpus(void); 6 | 7 | #endif /* OPC_CPU_H */ 8 | -------------------------------------------------------------------------------- /src/create_latex_API_doc.c: -------------------------------------------------------------------------------- 1 | #include "main.api_help.h" 2 | 3 | int main(void) 4 | { 5 | main_API_create_latex_doc(); 6 | return 0; 7 | } 8 | 9 | -------------------------------------------------------------------------------- /src/export.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_LEXPORT_H 2 | #define OPC_LEXPORT_H 3 | 4 | #include "object.h" 5 | #include "vector.h" 6 | 7 | struct export_state; 8 | 9 | struct export_state* export_create_state(void); 10 | void export_destroy_state(struct export_state* state); 11 | void export_add_searchpath(struct export_state* state, const char* path); 12 | void export_set_basename(struct export_state* state, const char* filename); 13 | void export_set_export_options(struct export_state* state, const char* const* exportoptions); 14 | void export_set_namecontext_expansion(struct export_state* state, int expand); 15 | void export_disable_ports(struct export_state* state); 16 | void export_disable_malformed_shapes(struct export_state* state); 17 | void export_set_write_children_ports(struct export_state* state, int writechildrenports); 18 | void export_set_bus_delimiters(struct export_state* state, char leftdelim, char rightdelim); 19 | void export_set_exportname(struct export_state* state, const char* exportname); 20 | const char* export_get_layername(const struct export_state* state); 21 | 22 | char* export_get_export_layername(struct const_vector* searchpaths, const char* exportname); 23 | int export_write_toplevel(struct object* toplevel, struct export_state* state); 24 | 25 | #endif // OPC_LEXPORT_H 26 | -------------------------------------------------------------------------------- /src/export_writer.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_EXPORT_WRITER 2 | #define OPC_EXPORT_WRITER 3 | 4 | #include "lua/lua.h" 5 | #include "export_common.h" 6 | #include "hashmap.h" 7 | 8 | struct export_writer; 9 | 10 | struct export_writer* export_writer_create_lua(lua_State* L, struct export_data* data); 11 | struct export_writer* export_writer_create_C(const struct export_functions* funcs, struct export_data* data); 12 | void export_writer_destroy(struct export_writer* writer); 13 | int export_writer_write_cell(struct export_writer* writer, const struct object* cell, int write_ports, char leftdelim, char rightdelim); 14 | int export_writer_write_toplevel(struct export_writer* writer, const struct object* object, int expand_namecontext, int writeports, int writechildrenports, int write_malformed, char leftdelim, char rightdelim); 15 | 16 | #endif // OPC_EXPORT_WRITER 17 | 18 | -------------------------------------------------------------------------------- /src/filesystem.c: -------------------------------------------------------------------------------- 1 | #include "filesystem.h" 2 | 3 | #include "lua/lauxlib.h" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | int filesystem_mkdir(const char* path) 13 | { 14 | mode_t mode = 0777; 15 | 16 | /* 17 | Code by Yaroslav Stavnichiy, taken from https://stackoverflow.com/questions/2336242/recursive-mkdir-system-call-on-unix 18 | Slightly modified for use in lua 19 | >> 20 | */ 21 | for (char* p = strchr(path + 1, '/'); p; p = strchr(p + 1, '/')) 22 | { 23 | *p = '\0'; 24 | if (mkdir(path, mode) == -1) { 25 | if (errno != EEXIST) { 26 | *p = '/'; 27 | return 0; 28 | } 29 | } 30 | *p = '/'; 31 | } 32 | /* << */ 33 | /* create last part of path */ 34 | if (mkdir(path, mode) == -1) { 35 | if (errno != EEXIST) { 36 | return 0; 37 | } 38 | } 39 | 40 | return 1; 41 | } 42 | 43 | int filesystem_exists(const char* path) 44 | { 45 | return access(path, F_OK) == 0; 46 | } 47 | 48 | static int lfilesystem_mkdir(lua_State* L) 49 | { 50 | const char* path = lua_tostring(L, 1); 51 | int ret = filesystem_mkdir(path); 52 | lua_pushboolean(L, ret); 53 | return 1; 54 | } 55 | 56 | static int lfilesystem_exists(lua_State* L) 57 | { 58 | const char* path = lua_tostring(L, 1); 59 | if(access(path, F_OK) == 0) 60 | { 61 | lua_pushboolean(L, 1); 62 | } 63 | else 64 | { 65 | lua_pushboolean(L, 0); 66 | } 67 | return 1; 68 | } 69 | 70 | int open_lfilesystem_lib(lua_State* L) 71 | { 72 | static const luaL_Reg modfuncs[] = 73 | { 74 | { "mkdir", lfilesystem_mkdir }, 75 | { "exists", lfilesystem_exists }, 76 | { NULL, NULL } 77 | }; 78 | luaL_newlib(L, modfuncs); 79 | lua_setglobal(L, LFILESYSTEMMODULE); 80 | 81 | return 0; 82 | } 83 | -------------------------------------------------------------------------------- /src/filesystem.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_FILESYSTEM_H 2 | #define OPC_FILESYSTEM_H 3 | 4 | #include "lua/lua.h" 5 | 6 | int filesystem_mkdir(const char* path); 7 | int filesystem_exists(const char* path); 8 | 9 | #define LFILESYSTEMMODULE "filesystem" 10 | 11 | int open_lfilesystem_lib(lua_State* L); 12 | 13 | #endif /* OPC_FILESYSTEM_H */ 14 | -------------------------------------------------------------------------------- /src/gdsexport.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_GDSEXPORT_H 2 | #define OPC_GDSEXPORT_H 3 | 4 | #include "export_common.h" 5 | 6 | struct export_functions* gdsexport_get_export_functions(void); 7 | 8 | #endif // OPC_GDSEXPORT_H 9 | -------------------------------------------------------------------------------- /src/gdsparser.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_GDSPARSER_H 2 | #define OPC_GDSPARSER_H 3 | 4 | #include "lua/lua.h" 5 | 6 | #include "vector.h" 7 | 8 | struct vector* gdsparser_create_layermap(const char* filename); 9 | void gdsparser_destroy_layermap(struct vector* layermap); 10 | int gdsparser_read_stream(const char* filename, const char* importname, const struct vector* layermap, const struct vector* ignorelpp, int16_t* ablayer, int16_t* abpurpose); 11 | int gdsparser_show_records(const char* filename, int raw); 12 | int gdsparser_show_cell_definitions(const char* filename); 13 | void gdsparser_show_cell_hierarchy(const char* filename, size_t depth); 14 | 15 | #endif /* OPC_GDSPARSER_H */ 16 | -------------------------------------------------------------------------------- /src/generate_manpage.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "cmdoptions.h" 4 | 5 | int main(void) 6 | { 7 | struct cmdoptions* cmdoptions = cmdoptions_create(); 8 | #include "cmdoptions_def.c" // yes, I did that 9 | puts(".TH opc 1 \"29 Aug 2022\" \"1.0\" \"opc man page\""); 10 | puts(".SH NAME"); 11 | puts("opc \\- parametric and technology-independent IC layout generator"); 12 | puts(".SH SYNOPSIS"); 13 | puts("opc [--cell cellname] [--technology technology] [--export export]"); 14 | puts(".SH DESCRIPTION"); 15 | puts(".B opc "); 16 | puts("is a technology-independent layout generator for integrated circuits with support for parametric cells."); 17 | cmdoptions_export_manpage(cmdoptions); 18 | puts(".SH AUTHOR"); 19 | puts("Patrick Kurth "); 20 | 21 | cmdoptions_destroy(cmdoptions); 22 | return 0; 23 | } 24 | 25 | -------------------------------------------------------------------------------- /src/graphics.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_GRAPHICS_H 2 | #define OPC_GRAPHICS_H 3 | 4 | #include 5 | 6 | #include "point.h" 7 | #include "vector.h" 8 | 9 | void graphics_rasterize_line_segment(const struct point* startpt, const struct point* endpt, unsigned int grid, int allow45, struct vector* result); 10 | void graphics_rasterize_arc_segment(struct point* startpt, double startangle, double endangle, coordinate_t radius, int clockwise, unsigned int grid, int allow45, struct vector* result); 11 | void graphics_rasterize_cubic_bezier_segment(const struct point* startpt, const struct point* cpt1, const struct point* cpt2, const struct point* endpt, unsigned int grid, int allow45, struct vector* result); 12 | 13 | struct vector* graphics_cubic_bezier(const struct const_vector* curve); 14 | 15 | #endif // OPC_GRAPHICS_H 16 | -------------------------------------------------------------------------------- /src/hashmap.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_HASHMAP_H 2 | #define OPC_HASHMAP_H 3 | 4 | struct hashmap; 5 | struct hashmap* hashmap_create(void); 6 | void hashmap_destroy(struct hashmap* map, void (*destructor)(void*)); 7 | void hashmap_insert(struct hashmap* map, const char* key, void* value); 8 | int hashmap_exists(const struct hashmap* map, const char* key); 9 | void* hashmap_get(struct hashmap* map, const char* key); 10 | const void* hashmap_get_const(const struct hashmap* map, const char* key); 11 | 12 | // iterator 13 | struct hashmap_iterator; 14 | struct hashmap_iterator* hashmap_iterator_create(struct hashmap* map); 15 | int hashmap_iterator_is_valid(const struct hashmap_iterator* iterator); 16 | const char* hashmap_iterator_key(const struct hashmap_iterator* iterator); 17 | void* hashmap_iterator_value(struct hashmap_iterator* iterator); 18 | void hashmap_iterator_next(struct hashmap_iterator* iterator); 19 | void hashmap_iterator_destroy(struct hashmap_iterator* iterator); 20 | 21 | // const iterator 22 | struct hashmap_const_iterator; 23 | struct hashmap_const_iterator* hashmap_const_iterator_create(const struct hashmap* map); 24 | int hashmap_const_iterator_is_valid(struct hashmap_const_iterator* iterator); 25 | const char* hashmap_const_iterator_key(struct hashmap_const_iterator* iterator); 26 | const void* hashmap_const_iterator_value(struct hashmap_const_iterator* iterator); 27 | void hashmap_const_iterator_next(struct hashmap_const_iterator* iterator); 28 | void hashmap_const_iterator_destroy(struct hashmap_const_iterator* iterator); 29 | 30 | #endif // OPC_HASHMAP_H 31 | -------------------------------------------------------------------------------- /src/info.c: -------------------------------------------------------------------------------- 1 | #include "info.h" 2 | 3 | #include 4 | 5 | void info_cellinfo(struct object* cell) 6 | { 7 | printf("number of shapes: %ld\n", object_get_shapes_size(cell)); 8 | 9 | //print("used layers:") 10 | //for _, lpp in cell:layers() do 11 | // print(string.format(" %s", lpp:str())) 12 | //end 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/info.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_INFO_H 2 | #define OPC_INFO_H 3 | 4 | #include "object.h" 5 | 6 | void info_cellinfo(struct object* cell); 7 | 8 | #endif // OPC_INFO_H 9 | -------------------------------------------------------------------------------- /src/lcheck.c: -------------------------------------------------------------------------------- 1 | #include "lcheck.h" 2 | 3 | void lcheck_check_numargs1(lua_State* L, int numargs, const char* funcname) 4 | { 5 | int top = lua_gettop(L); 6 | if(top != numargs) 7 | { 8 | lua_pushfstring(L, "%s: expected %d arguments, got %d", funcname, numargs, top); 9 | lua_error(L); 10 | } 11 | } 12 | 13 | void lcheck_check_numargs2(lua_State* L, int numargs1, int numargs2, const char* funcname) 14 | { 15 | int top = lua_gettop(L); 16 | if(top != numargs1 && top != numargs2) 17 | { 18 | lua_pushfstring(L, "%s: expected %d or %d arguments, got %d", funcname, numargs1, numargs2, top); 19 | lua_error(L); 20 | } 21 | } 22 | 23 | void lcheck_check_numargs3(lua_State* L, int numargs1, int numargs2, int numargs3, const char* funcname) 24 | { 25 | int top = lua_gettop(L); 26 | if(top != numargs1 && top != numargs2 && top != numargs3) 27 | { 28 | lua_pushfstring(L, "%s: expected %d, %d or %d arguments, got %d", funcname, numargs1, numargs2, numargs3, top); 29 | lua_error(L); 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /src/lcheck.h: -------------------------------------------------------------------------------- 1 | #include "lua/lua.h" 2 | 3 | void lcheck_check_numargs1(lua_State* L, int numargs, const char* funcname); 4 | void lcheck_check_numargs2(lua_State* L, int numargs1, int numargs2, const char* funcname); 5 | void lcheck_check_numargs3(lua_State* L, int numargs1, int numargs2, int numargs3, const char* funcname); 6 | 7 | -------------------------------------------------------------------------------- /src/ldebug.c: -------------------------------------------------------------------------------- 1 | #include "ldebug.h" 2 | 3 | #include 4 | 5 | void ldebug_dump_stack(lua_State *L) 6 | { 7 | int i; 8 | int top = lua_gettop(L); 9 | puts("#### BOS ####"); 10 | for(i = top; i >= 1; i--) 11 | { 12 | int t = lua_type(L, i); 13 | switch(t) 14 | { 15 | case LUA_TSTRING: 16 | printf("%i (%i) = string: \"%s\"", i, i - (top + 1), lua_tostring(L, i)); 17 | break; 18 | 19 | case LUA_TBOOLEAN: 20 | printf("%i (%i) = %s", i, i - (top + 1), lua_toboolean(L, i) ? "true" : "false"); 21 | break; 22 | 23 | case LUA_TNUMBER: 24 | printf("%i (%i) = %g", i, i - (top + 1), lua_tonumber(L, i)); 25 | break; 26 | 27 | case LUA_TUSERDATA: 28 | /* FIXME: broken, but I don't know why 29 | if(lua_getmetatable(L, i)) 30 | { 31 | lua_pushstring(L, "__tostring"); 32 | lua_gettable(L, -2); 33 | if(lua_isnil(L, -1)) 34 | { 35 | lua_pop(L, 1); // pop nil 36 | lua_pushstring(L, "userdata"); 37 | } 38 | else 39 | { 40 | lua_pushvalue(L, i); 41 | lua_call(L, 1, 1); 42 | } 43 | lua_insert(L, -2); 44 | lua_pop(L, 1); // pop meta table 45 | } 46 | else 47 | { 48 | lua_pushstring(L, "userdata"); 49 | } 50 | const char* tag = lua_tostring(L, -1); 51 | printf("%i (%i) = %s: %p", i, i - (top + 1), tag, lua_touserdata(L, i)); 52 | lua_pop(L, 1); 53 | */ 54 | printf("%i (%i) = %s: %p", i, i - (top + 1), "userdata", lua_touserdata(L, i)); 55 | break; 56 | 57 | default: 58 | printf("%i (%i) = %s", i, i - (top + 1), lua_typename(L, t)); 59 | break; 60 | } 61 | putchar('\n'); 62 | } 63 | puts("#### EOS ####"); 64 | } 65 | -------------------------------------------------------------------------------- /src/ldebug.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_LDEBUG_H 2 | #define OPC_LDEBUG_H 3 | 4 | #include "lua/lua.h" 5 | 6 | void ldebug_dump_stack(lua_State *L); 7 | 8 | #endif /* OPC_LDEBUG_H */ 9 | -------------------------------------------------------------------------------- /src/ldir.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_LDIR_H 2 | #define OPC_LDIR_H 3 | 4 | #include "lua/lua.h" 5 | 6 | int open_ldir_lib(lua_State* L); 7 | 8 | #endif // OPC_LDIR_H 9 | -------------------------------------------------------------------------------- /src/lgenerics.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_LGENERICS_H 2 | #define OPC_LGENERICS_H 3 | 4 | #include "lua/lua.h" 5 | 6 | #define LGENERICSMODULE "generics" 7 | 8 | int open_lgenerics_lib(lua_State* L); 9 | void* generics_check_generics(lua_State* L, int idx); 10 | 11 | #endif /* OPC_LGENERICS_H */ 12 | -------------------------------------------------------------------------------- /src/lgeometry.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_LGEOMETRY_H 2 | #define OPC_LGEOMETRY_H 3 | 4 | #include "lua/lua.h" 5 | 6 | #define LGEOMETRYMODULE "geometry" 7 | 8 | int open_lgeometry_lib(lua_State* L); 9 | 10 | #endif /* OPC_LGEOMETRY_H */ 11 | -------------------------------------------------------------------------------- /src/lobject.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_LOBJECT_H 2 | #define OPC_LOBJECT_H 3 | 4 | #include "lua/lua.h" 5 | #include "object.h" 6 | 7 | #define LOBJECTMODULE "object" 8 | 9 | struct lobject; 10 | 11 | int lobject_create(lua_State* L); 12 | struct lobject* lobject_check(lua_State* L, int idx); 13 | struct lobject* lobject_check_soft(lua_State* L, int idx); 14 | struct lobject* lobject_adapt_owning(lua_State* L, struct object* cell); 15 | struct lobject* lobject_adapt_non_owning(lua_State* L, struct object* cell); 16 | struct object* lobject_get_unchecked(struct lobject* lobject); 17 | struct object* lobject_get(lua_State* L, struct lobject* lobject); 18 | struct object* lobject_get_full(lua_State* L, struct lobject* lobject); 19 | const struct object* lobject_get_const(struct lobject* lobject); 20 | void lobject_check_proxy(lua_State* L, struct lobject* lobject); 21 | void lobject_disown(struct lobject* lobject); 22 | void lobject_mark_as_unusable(struct lobject* lobject); 23 | 24 | int open_lobject_lib(lua_State* L); 25 | 26 | #endif // OPC_LOBJECT_H 27 | -------------------------------------------------------------------------------- /src/lplacement.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_LPLACEMENT_H 2 | #define OPC_LPLACEMENT_H 3 | 4 | #include "lua/lua.h" 5 | 6 | #include "polygon.h" 7 | 8 | #define LPLACEMENTMODULE "placement" 9 | 10 | void lplacement_create_exclude_vectors(lua_State* L, struct polygon_container** excludes, int idx); 11 | int open_lplacement_lib(lua_State* L); 12 | 13 | #endif // OPC_LPLACEMENT_H 14 | -------------------------------------------------------------------------------- /src/lplacer.c: -------------------------------------------------------------------------------- 1 | #include "lua/lua.h" 2 | #include "lua/lauxlib.h" 3 | 4 | #include "lplacer_nonoverlapping.h" 5 | #include "lplacer_classic.h" 6 | 7 | int lplacer_place_simulated_annealing(lua_State* L) 8 | { 9 | lplacer_place_classic(L); 10 | return 1; 11 | } 12 | 13 | int open_lplacer_lib(lua_State* L) 14 | { 15 | static const luaL_Reg modfuncs[] = 16 | { 17 | { "place_simulated_annealing", lplacer_place_simulated_annealing }, 18 | { "place_nonoverlapping", lplacer_place_nonoverlapping }, 19 | { "place_classic", lplacer_place_classic }, 20 | { NULL, NULL } 21 | }; 22 | lua_newtable(L); 23 | luaL_setfuncs(L, modfuncs, 0); 24 | lua_setglobal(L, "placer"); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /src/lplacer.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_LPLACER_H 2 | #define OPC_LPLACER_H 3 | 4 | #include "lua/lua.h" 5 | 6 | int open_lplacer_lib(lua_State* L); 7 | 8 | #endif /* OPC_LPLACER_H */ 9 | -------------------------------------------------------------------------------- /src/lplacer_classic.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_LPLACER_CLASSIC_H 2 | #define OPC_LPLACER_CLASSIC_H 3 | 4 | #include "lua/lua.h" 5 | 6 | int lplacer_place_classic(lua_State* L); 7 | 8 | #endif /* OPC_LPLACER_CLASSIC_H */ 9 | -------------------------------------------------------------------------------- /src/lplacer_common.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_LPLACER_COMMON_H 2 | #define OPC_LPLACER_COMMON_H 3 | 4 | #include "lua/lua.h" 5 | 6 | #include 7 | 8 | #include "hashmap.h" 9 | 10 | struct basic_cell { 11 | unsigned int instance; 12 | unsigned int reference; 13 | unsigned int width; 14 | struct net** nets; 15 | unsigned int* pinoffset; 16 | unsigned int num_conns; 17 | }; 18 | 19 | void placer_initialize_base_cell(lua_State* L, struct basic_cell* base, size_t index, struct hashmap* netmap); 20 | void placer_destroy_base_cell_contents(struct basic_cell* base); 21 | 22 | struct floorplan { 23 | unsigned int floorplan_width; 24 | unsigned int floorplan_height; 25 | unsigned int desired_row_width; 26 | // limiter window 27 | int limiter_width; 28 | int limiter_height; 29 | }; 30 | 31 | struct floorplan* placer_create_floorplan(lua_State* L); 32 | void placer_destroy_floorplan(struct floorplan* floorplan); 33 | 34 | // lua result 35 | typedef int* (*row_access_func_t)(const void*, unsigned int); 36 | void placer_create_lua_result(lua_State* L, void* block, row_access_func_t, struct floorplan* floorplan); 37 | 38 | #endif /* OPC_LPLACER_COMMON_H */ 39 | -------------------------------------------------------------------------------- /src/lplacer_floorplan.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_LPLACER_FLOORPLAN_H 2 | #define OPC_LPLACER_FLOORPLAN_H 3 | 4 | #endif /* OPC_LPLACER_FLOORPLAN_H */ 5 | -------------------------------------------------------------------------------- /src/lplacer_nonoverlapping.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_LPLACER_NONOVERLAPPING_H 2 | #define OPC_LPLACER_NONOVERLAPPING_H 3 | 4 | #include "lua/lua.h" 5 | 6 | int lplacer_place_nonoverlapping(lua_State* L); 7 | 8 | #endif /* OPC_LPLACER_NONOVERLAPPING_H */ 9 | -------------------------------------------------------------------------------- /src/lplacer_rand.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_LPLACER_RAND_H 2 | #define OPC_LPLACER_RAND_H 3 | 4 | typedef unsigned long Rand64; 5 | struct RanState { 6 | Rand64 s[4]; 7 | }; 8 | 9 | void randseed (struct RanState *state, unsigned long n1, unsigned long n2); 10 | long _lua_randi(struct RanState* state, long low, long up); 11 | int random_choice(struct RanState* rstate, double prob); 12 | 13 | struct UPRNG 14 | { 15 | unsigned int* numbers; 16 | unsigned int size; 17 | unsigned int index; 18 | struct RanState* rstate; 19 | }; 20 | 21 | struct UPRNG* UPRNG_init(unsigned int size, struct RanState* rstate); 22 | void UPRNG_destroy(struct UPRNG* rng); 23 | void UPRNG_resize(struct UPRNG** rng, unsigned int size); 24 | unsigned int UPRNG_next(struct UPRNG* rng); 25 | 26 | #endif // OPC_LPLACER_RAND_H 27 | -------------------------------------------------------------------------------- /src/lpoint.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_LPOINT_H 2 | #define OPC_LPOINT_H 3 | 4 | #include "lua/lua.h" 5 | 6 | #include "point.h" 7 | 8 | #define LPOINTMODULE "point" 9 | 10 | struct lpoint; 11 | 12 | struct lpoint* lpoint_create_internal_xy(lua_State* L, coordinate_t x, coordinate_t y); 13 | struct lpoint* lpoint_create_internal_pt(lua_State* L, const struct point* pt); 14 | struct lpoint* lpoint_adapt_point(lua_State* L, struct point* pt); 15 | struct lpoint* lpoint_takeover_point(lua_State* L, struct point* pt); 16 | int lpoint_create(lua_State* L); 17 | int lpoint_copy(lua_State* L); 18 | const struct point* lpoint_get(const struct lpoint* pt); 19 | coordinate_t lpoint_checkcoordinate(lua_State* L, int idx, const char* coordinate); 20 | struct lpoint* lpoint_checkpoint(lua_State* L, int idx); 21 | int lpoint_is_point(lua_State* L, int idx); 22 | 23 | int open_lpoint_lib(lua_State* L); 24 | 25 | #endif // OPC_LPOINT_H 26 | -------------------------------------------------------------------------------- /src/lpostprocess.c: -------------------------------------------------------------------------------- 1 | #include "lpostprocess.h" 2 | 3 | #include "lua/lauxlib.h" 4 | 5 | #include "postprocess.h" 6 | #include "lobject.h" 7 | 8 | int lpostprocess_remove_layer_shapes_flat(lua_State* L) 9 | { 10 | struct lobject* cell = lobject_check(L, 1); 11 | const struct generics* layer = lua_touserdata(L, 2); 12 | postprocess_remove_layer_shapes_flat(lobject_get(L, cell), layer); 13 | return 0; 14 | } 15 | 16 | int lpostprocess_remove_layer_shapes(lua_State* L) 17 | { 18 | struct lobject* cell = lobject_check(L, 1); 19 | const struct generics* layer = lua_touserdata(L, 2); 20 | postprocess_remove_layer_shapes(lobject_get(L, cell), layer); 21 | return 0; 22 | } 23 | 24 | int open_lpostprocess(lua_State* L) 25 | { 26 | lua_newtable(L); 27 | static const luaL_Reg modfuncs[] = 28 | { 29 | { "remove_layer_shapes_flat", lpostprocess_remove_layer_shapes_flat }, 30 | { "remove_layer_shapes", lpostprocess_remove_layer_shapes }, 31 | { NULL, NULL } 32 | }; 33 | luaL_setfuncs(L, modfuncs, 0); 34 | lua_setglobal(L, "postprocess"); 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /src/lpostprocess.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_LPOSTPROCESS_H 2 | #define OPC_LPOSTPROCESS_H 3 | 4 | #include "lua/lua.h" 5 | 6 | int open_lpostprocess(lua_State* L); 7 | 8 | #endif // OPC_LPOSTPROCESS_H 9 | -------------------------------------------------------------------------------- /src/lrouter.h: -------------------------------------------------------------------------------- 1 | #ifndef LROUTER_H 2 | #define LROUTER_H 3 | 4 | #include "lua/lua.h" 5 | 6 | int open_lrouter_lib(lua_State* L); 7 | 8 | #endif // LROUTER_H 9 | -------------------------------------------------------------------------------- /src/lrouter_field.h: -------------------------------------------------------------------------------- 1 | #ifndef LROUTER_FIELD_H 2 | #define LROUTER_FIELD_H 3 | 4 | /* special values for a point in one layer */ 5 | #define UNVISITED -1 6 | #define PATH -2 7 | #define PORT -3 8 | #define VIA -4 9 | #define BLOCKAGE -5 10 | 11 | #include 12 | 13 | /* point of the field struct */ 14 | struct rpoint { 15 | unsigned int x, y, z; 16 | int score; 17 | }; 18 | 19 | struct field; 20 | struct field* field_init(size_t width, size_t height, size_t num_layers); 21 | struct field* field_copy(struct field *field); 22 | void field_restore(struct field *original, struct field *copy); 23 | void field_destroy(struct field* field); 24 | void field_print(struct field* field, int layer); 25 | void field_unprint(size_t size); 26 | void field_create_blockage(struct field* field, struct rpoint* start, struct rpoint* end); 27 | 28 | struct rpoint *point_new(int x, int y, int z, unsigned int score); 29 | int point_get_score(const struct rpoint *point); 30 | 31 | size_t field_get_width(struct field* field); 32 | size_t field_get_height(struct field* field); 33 | size_t field_get_num_layers(struct field* field); 34 | 35 | int field_is_field_point(const struct field* field, struct rpoint pt); 36 | int field_is_visitable(const struct field* field, size_t x, size_t y, size_t z); 37 | 38 | void field_set(struct field* field, size_t x, size_t y, size_t z, int what); 39 | int field_get(struct field* field, size_t x, size_t y, size_t z); 40 | struct net *field_get_net(struct field* field, size_t x, size_t y, size_t z); 41 | void field_set_net(struct field* field, size_t x, size_t y, size_t z, struct net *what); 42 | 43 | /* resets the values in the field for a next iteration (keeps special values) */ 44 | void field_reset(struct field* field); 45 | 46 | #endif /* LROUTER_FIELD_H */ 47 | -------------------------------------------------------------------------------- /src/lrouter_min_heap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: lrouter_min_heap.h 3 | * Desc: Program showing various operations on a binary min heap 4 | * Author: Robin Thomas 5 | * Taken from: https://github.com/robin-thomas/min-heap 6 | * Changed and restructured by Philipp Nickel to store struct rpoint 7 | */ 8 | 9 | #ifndef LROUTER_MIN_HEAP_H 10 | #define LROUTER_MIN_HEAP_H 11 | 12 | #include "lrouter_field.h" 13 | 14 | struct minheap; 15 | 16 | /* Function to initialize the min heap with size = 0 */ 17 | struct minheap *heap_init(void); 18 | void heap_destroy(struct minheap* heap); 19 | 20 | /* 21 | * Function to insert a node into the min heap, by allocating space for 22 | * that node in the heap and also making sure that the heap property 23 | * and shape propety are never violated. 24 | * Changed smaller to smaller or equal so it works as a FIFO queue for same val 25 | * nodes 26 | */ 27 | void heap_insert_point(struct minheap *hp, int x, int y, int z, unsigned int score); 28 | 29 | /* 30 | * Function to get a node from the min heap 31 | * It shall remove the root node, and place the last node in its place 32 | * and then call heapify function to make sure that the heap property 33 | * is never violated 34 | */ 35 | struct rpoint *heap_get_point(struct minheap *hp); 36 | 37 | /* Function to display all the nodes in the min heap by inorder traversal */ 38 | void heap_inorder_trav(struct minheap *hp, size_t i); 39 | 40 | int heap_empty(struct minheap* heap); 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/lrouter_moves.c: -------------------------------------------------------------------------------- 1 | #include "lua/lua.h" 2 | #include "lua/lauxlib.h" 3 | 4 | #include "lrouter_moves.h" 5 | 6 | static void _create(lua_State* L, const char* type) 7 | { 8 | lua_newtable(L); 9 | lua_pushstring(L, type); 10 | lua_setfield(L, -2, "type"); 11 | } 12 | 13 | void moves_create_port(lua_State *L, const char *name, const char *port, int nodraw) 14 | { 15 | _create(L, "point"); 16 | //lua_pushfstring(L, "cells[\"%s\"]:get_anchor(\"%s\"):translate(bp.routingwidth / 2, bp.routingwidth / 2)", name, port); 17 | lua_pushfstring(L, "cells[\"%s\"]:get_anchor(\"%s\")", name, port); 18 | lua_setfield(L, -2, "where"); 19 | lua_pushboolean(L, nodraw); 20 | lua_setfield(L, -2, "nodraw"); 21 | } 22 | 23 | void moves_create_via(lua_State *L, int z) 24 | { 25 | _create(L, "via"); 26 | lua_pushinteger(L, z); 27 | lua_setfield(L, -2, "z"); 28 | lua_pushboolean(L, 0); 29 | lua_setfield(L, -2, "nodraw"); 30 | } 31 | 32 | void moves_create_via_nodraw(lua_State *L, int z) 33 | { 34 | _create(L, "via"); 35 | lua_pushinteger(L, z); 36 | lua_setfield(L, -2, "z"); 37 | lua_pushboolean(L, 1); 38 | lua_setfield(L, -2, "nodraw"); 39 | } 40 | 41 | 42 | void moves_create_delta(lua_State *L, dir_t dir, int dist) 43 | { 44 | _create(L, "delta"); 45 | lua_pushinteger(L, -dist); 46 | if(dir == X_DIR) 47 | { 48 | lua_setfield(L, -2, "x"); 49 | } 50 | else if(dir == Y_DIR) 51 | { 52 | lua_setfield(L, -2, "y"); 53 | } 54 | } 55 | 56 | void moves_create_shift(lua_State *L, int x, int y) 57 | { 58 | _create(L, "shift"); 59 | lua_pushinteger(L, x); 60 | lua_setfield(L, -2, "x"); 61 | lua_pushinteger(L, y); 62 | lua_setfield(L, -2, "y"); 63 | } 64 | 65 | -------------------------------------------------------------------------------- /src/lrouter_moves.h: -------------------------------------------------------------------------------- 1 | #ifndef LROUTER_MOVES_H 2 | #define LROUTER_MOVES_H 3 | 4 | typedef enum { X_DIR, Y_DIR } dir_t; 5 | 6 | /* 7 | * all move functions must be pushed into a bigger table (e.g. with all the moves) 8 | * in the end to be put in a table around it to complete the whole route 9 | * e.g.: 10 | * 11 | * moves_create_via(L, -2); 12 | * lua_rawseti(L, -2, 2); 13 | */ 14 | 15 | void moves_create_port(lua_State *L, const char *name, const char *port, int nodraw); 16 | void moves_create_via(lua_State *L, int z); 17 | void moves_create_via_nodraw(lua_State *L, int z); 18 | void moves_create_delta(lua_State *L, dir_t dir, int dist); 19 | void moves_create_shift(lua_State *L, int x, int y); 20 | 21 | #endif //LROUTER_MOVES_H 22 | -------------------------------------------------------------------------------- /src/lrouter_net.h: -------------------------------------------------------------------------------- 1 | #ifndef LROUTER_NET_H 2 | #define LROUTER_NET_H 3 | 4 | #include "lrouter_field.h" 5 | #include "vector.h" 6 | 7 | #include 8 | #include 9 | 10 | #define NO_SUFFIX -1 11 | 12 | struct position { 13 | char* instance; 14 | char* port; 15 | unsigned int x; 16 | unsigned int y; 17 | unsigned int z; 18 | }; 19 | 20 | struct net; 21 | 22 | struct net* net_create(const char* name, int suffixnum, struct vector *positions); 23 | void net_destroy_position(void *pp); 24 | void net_destroy(void* np); 25 | void net_restore_positions(struct net *original, struct net *copy); 26 | struct net *net_copy(const struct net *net); 27 | 28 | void net_mark_as_routed(struct net* net); 29 | int net_is_routed(const struct net* net); 30 | 31 | const char* net_get_name(const struct net* net); 32 | int net_get_size(const struct net* net); 33 | size_t net_get_endpoints_size(const struct net* net); 34 | const struct position *net_get_position(const struct net *net, size_t i); 35 | const struct position *net_get_endpoint(const struct net *net, size_t i); 36 | struct vector* net_make_deltas(struct vector* deltas); 37 | 38 | /* 39 | * sorts the nets in ascending order of number of 40 | * pins within their bounding boxes 41 | */ 42 | void net_sort_nets(struct vector* nets); 43 | 44 | /* fill ports of nets into field */ 45 | void nets_fill_ports(struct vector* nets, struct field* field); 46 | void net_fill_ports(struct net* net, struct field* field); 47 | 48 | void net_append_position(struct net *net, struct position *position); 49 | void net_remove_position(struct net *net, unsigned int i); 50 | 51 | struct position* net_create_position(const char *instance, const char *port, unsigned int x, unsigned int y, unsigned int z); 52 | const char *net_position_get_inst(const struct position *pos); 53 | const char *net_position_get_port(const struct position *pos); 54 | void* net_copy_position(const void* pos); 55 | struct rpoint *net_position_to_point(const struct position *pos); 56 | struct position *net_point_to_position(const struct rpoint *point); 57 | const struct position *net_get_position_at_point(const struct net *net, const struct rpoint *point); 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /src/lrouter_queue.h: -------------------------------------------------------------------------------- 1 | #ifndef LROUTER_QUEUE_H 2 | #define LROUTER_QUEUE_H 3 | 4 | #include "lrouter_field.h" 5 | 6 | /* 7 | * taken from 8 | * https://de.wikibooks.org/wiki/Algorithmen_und_Datenstrukturen_in_C/ 9 | * _Warteschlange 10 | * Modified by Philipp nickel 11 | */ 12 | 13 | struct queue; 14 | 15 | int queue_destroy(struct queue *queue); 16 | int queue_empty(struct queue *queue); 17 | void queue_clear(struct queue *queue); 18 | struct queue *queue_new(void); 19 | void *queue_dequeue(struct queue *queue); 20 | int queue_enqueue(struct queue *queue, void *data); 21 | int queue_len(struct queue *queue); 22 | void queue_print(struct queue *queue); 23 | void queue_reverse(struct queue *queue); 24 | void *queue_peek_nth_elem(struct queue *queue, unsigned int n); 25 | 26 | /* takes a queue and gives back the entries as a position_t array */ 27 | struct rpoint* queue_as_array(struct queue *queue); 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/lrouter_route.h: -------------------------------------------------------------------------------- 1 | #ifndef LROUTER_ROUTE_H 2 | #define LROUTER_ROUTE_H 3 | 4 | #include "lrouter_net.h" 5 | #include "lrouter_field.h" 6 | 7 | /* 8 | * use lee algorithm for routing, does backtrace & marks the path as blocked 9 | * when has_backtrace flag is set 10 | * returns the length of the route it found 11 | * -1 if it couldnt find a route 12 | */ 13 | struct vector* route(struct net *net, struct field* field); 14 | 15 | #endif // LROUTER_ROUTE_H 16 | -------------------------------------------------------------------------------- /src/lua/lapi.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lapi.h $ 3 | ** Auxiliary functions from Lua API 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lapi_h 8 | #define lapi_h 9 | 10 | 11 | #include "llimits.h" 12 | #include "lstate.h" 13 | 14 | 15 | /* Increments 'L->top', checking for stack overflows */ 16 | #define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \ 17 | "stack overflow");} 18 | 19 | 20 | /* 21 | ** If a call returns too many multiple returns, the callee may not have 22 | ** stack space to accommodate all results. In this case, this macro 23 | ** increases its stack space ('L->ci->top'). 24 | */ 25 | #define adjustresults(L,nres) \ 26 | { if ((nres) <= LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; } 27 | 28 | 29 | /* Ensure the stack has at least 'n' elements */ 30 | #define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \ 31 | "not enough elements in the stack") 32 | 33 | 34 | /* 35 | ** To reduce the overhead of returning from C functions, the presence of 36 | ** to-be-closed variables in these functions is coded in the CallInfo's 37 | ** field 'nresults', in a way that functions with no to-be-closed variables 38 | ** with zero, one, or "all" wanted results have no overhead. Functions 39 | ** with other number of wanted results, as well as functions with 40 | ** variables to be closed, have an extra check. 41 | */ 42 | 43 | #define hastocloseCfunc(n) ((n) < LUA_MULTRET) 44 | 45 | /* Map [-1, inf) (range of 'nresults') into (-inf, -2] */ 46 | #define codeNresults(n) (-(n) - 3) 47 | #define decodeNresults(n) (-(n) - 3) 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /src/lua/lctype.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lctype.h $ 3 | ** 'ctype' functions for Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lctype_h 8 | #define lctype_h 9 | 10 | #include "lua.h" 11 | 12 | 13 | /* 14 | ** WARNING: the functions defined here do not necessarily correspond 15 | ** to the similar functions in the standard C ctype.h. They are 16 | ** optimized for the specific needs of Lua. 17 | */ 18 | 19 | #if !defined(LUA_USE_CTYPE) 20 | 21 | #if 'A' == 65 && '0' == 48 22 | /* ASCII case: can use its own tables; faster and fixed */ 23 | #define LUA_USE_CTYPE 0 24 | #else 25 | /* must use standard C ctype */ 26 | #define LUA_USE_CTYPE 1 27 | #endif 28 | 29 | #endif 30 | 31 | 32 | #if !LUA_USE_CTYPE /* { */ 33 | 34 | #include 35 | 36 | #include "llimits.h" 37 | 38 | 39 | #define ALPHABIT 0 40 | #define DIGITBIT 1 41 | #define PRINTBIT 2 42 | #define SPACEBIT 3 43 | #define XDIGITBIT 4 44 | 45 | 46 | #define MASK(B) (1 << (B)) 47 | 48 | 49 | /* 50 | ** add 1 to char to allow index -1 (EOZ) 51 | */ 52 | #define testprop(c,p) (luai_ctype_[(c)+1] & (p)) 53 | 54 | /* 55 | ** 'lalpha' (Lua alphabetic) and 'lalnum' (Lua alphanumeric) both include '_' 56 | */ 57 | #define lislalpha(c) testprop(c, MASK(ALPHABIT)) 58 | #define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT))) 59 | #define lisdigit(c) testprop(c, MASK(DIGITBIT)) 60 | #define lisspace(c) testprop(c, MASK(SPACEBIT)) 61 | #define lisprint(c) testprop(c, MASK(PRINTBIT)) 62 | #define lisxdigit(c) testprop(c, MASK(XDIGITBIT)) 63 | 64 | 65 | /* 66 | ** In ASCII, this 'ltolower' is correct for alphabetic characters and 67 | ** for '.'. That is enough for Lua needs. ('check_exp' ensures that 68 | ** the character either is an upper-case letter or is unchanged by 69 | ** the transformation, which holds for lower-case letters and '.'.) 70 | */ 71 | #define ltolower(c) \ 72 | check_exp(('A' <= (c) && (c) <= 'Z') || (c) == ((c) | ('A' ^ 'a')), \ 73 | (c) | ('A' ^ 'a')) 74 | 75 | 76 | /* one entry for each character and for -1 (EOZ) */ 77 | LUAI_DDEC(const lu_byte luai_ctype_[UCHAR_MAX + 2];) 78 | 79 | 80 | #else /* }{ */ 81 | 82 | /* 83 | ** use standard C ctypes 84 | */ 85 | 86 | #include 87 | 88 | 89 | #define lislalpha(c) (isalpha(c) || (c) == '_') 90 | #define lislalnum(c) (isalnum(c) || (c) == '_') 91 | #define lisdigit(c) (isdigit(c)) 92 | #define lisspace(c) (isspace(c)) 93 | #define lisprint(c) (isprint(c)) 94 | #define lisxdigit(c) (isxdigit(c)) 95 | 96 | #define ltolower(c) (tolower(c)) 97 | 98 | #endif /* } */ 99 | 100 | #endif 101 | 102 | -------------------------------------------------------------------------------- /src/lua/ldebug.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldebug.h $ 3 | ** Auxiliary functions from Debug Interface module 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ldebug_h 8 | #define ldebug_h 9 | 10 | 11 | #include "lstate.h" 12 | 13 | 14 | #define pcRel(pc, p) (cast_int((pc) - (p)->code) - 1) 15 | 16 | 17 | /* Active Lua function (given call info) */ 18 | #define ci_func(ci) (clLvalue(s2v((ci)->func))) 19 | 20 | 21 | #define resethookcount(L) (L->hookcount = L->basehookcount) 22 | 23 | /* 24 | ** mark for entries in 'lineinfo' array that has absolute information in 25 | ** 'abslineinfo' array 26 | */ 27 | #define ABSLINEINFO (-0x80) 28 | 29 | 30 | /* 31 | ** MAXimum number of successive Instructions WiTHout ABSolute line 32 | ** information. (A power of two allows fast divisions.) 33 | */ 34 | #if !defined(MAXIWTHABS) 35 | #define MAXIWTHABS 128 36 | #endif 37 | 38 | 39 | LUAI_FUNC int luaG_getfuncline (const Proto *f, int pc); 40 | LUAI_FUNC const char *luaG_findlocal (lua_State *L, CallInfo *ci, int n, 41 | StkId *pos); 42 | LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o, 43 | const char *opname); 44 | LUAI_FUNC l_noret luaG_callerror (lua_State *L, const TValue *o); 45 | LUAI_FUNC l_noret luaG_forerror (lua_State *L, const TValue *o, 46 | const char *what); 47 | LUAI_FUNC l_noret luaG_concaterror (lua_State *L, const TValue *p1, 48 | const TValue *p2); 49 | LUAI_FUNC l_noret luaG_opinterror (lua_State *L, const TValue *p1, 50 | const TValue *p2, 51 | const char *msg); 52 | LUAI_FUNC l_noret luaG_tointerror (lua_State *L, const TValue *p1, 53 | const TValue *p2); 54 | LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1, 55 | const TValue *p2); 56 | LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...); 57 | LUAI_FUNC const char *luaG_addinfo (lua_State *L, const char *msg, 58 | TString *src, int line); 59 | LUAI_FUNC l_noret luaG_errormsg (lua_State *L); 60 | LUAI_FUNC int luaG_traceexec (lua_State *L, const Instruction *pc); 61 | 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /src/lua/lfunc.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lfunc.h $ 3 | ** Auxiliary functions to manipulate prototypes and closures 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lfunc_h 8 | #define lfunc_h 9 | 10 | 11 | #include "lobject.h" 12 | 13 | 14 | #define sizeCclosure(n) (cast_int(offsetof(CClosure, upvalue)) + \ 15 | cast_int(sizeof(TValue)) * (n)) 16 | 17 | #define sizeLclosure(n) (cast_int(offsetof(LClosure, upvals)) + \ 18 | cast_int(sizeof(TValue *)) * (n)) 19 | 20 | 21 | /* test whether thread is in 'twups' list */ 22 | #define isintwups(L) (L->twups != L) 23 | 24 | 25 | /* 26 | ** maximum number of upvalues in a closure (both C and Lua). (Value 27 | ** must fit in a VM register.) 28 | */ 29 | #define MAXUPVAL 255 30 | 31 | 32 | #define upisopen(up) ((up)->v != &(up)->u.value) 33 | 34 | 35 | #define uplevel(up) check_exp(upisopen(up), cast(StkId, (up)->v)) 36 | 37 | 38 | /* 39 | ** maximum number of misses before giving up the cache of closures 40 | ** in prototypes 41 | */ 42 | #define MAXMISS 10 43 | 44 | 45 | 46 | /* special status to close upvalues preserving the top of the stack */ 47 | #define CLOSEKTOP (-1) 48 | 49 | 50 | LUAI_FUNC Proto *luaF_newproto (lua_State *L); 51 | LUAI_FUNC CClosure *luaF_newCclosure (lua_State *L, int nupvals); 52 | LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nupvals); 53 | LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl); 54 | LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); 55 | LUAI_FUNC void luaF_newtbcupval (lua_State *L, StkId level); 56 | LUAI_FUNC void luaF_closeupval (lua_State *L, StkId level); 57 | LUAI_FUNC void luaF_close (lua_State *L, StkId level, int status, int yy); 58 | LUAI_FUNC void luaF_unlinkupval (UpVal *uv); 59 | LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); 60 | LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, 61 | int pc); 62 | 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /src/lua/linit.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: linit.c $ 3 | ** Initialization of libraries for lua.c and other clients 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #define linit_c 9 | #define LUA_LIB 10 | 11 | /* 12 | ** If you embed Lua in your program and need to open the standard 13 | ** libraries, call luaL_openlibs in your program. If you need a 14 | ** different set of libraries, copy this file to your project and edit 15 | ** it to suit your needs. 16 | ** 17 | ** You can also *preload* libraries, so that a later 'require' can 18 | ** open the library, which is already linked to the application. 19 | ** For that, do the following code: 20 | ** 21 | ** luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); 22 | ** lua_pushcfunction(L, luaopen_modname); 23 | ** lua_setfield(L, -2, modname); 24 | ** lua_pop(L, 1); // remove PRELOAD table 25 | */ 26 | 27 | #include "lprefix.h" 28 | 29 | 30 | #include 31 | 32 | #include "lua.h" 33 | 34 | #include "lualib.h" 35 | #include "lauxlib.h" 36 | 37 | 38 | /* 39 | ** these libs are loaded by lua.c and are readily available to any Lua 40 | ** program 41 | */ 42 | static const luaL_Reg loadedlibs[] = { 43 | {LUA_GNAME, luaopen_base}, 44 | {LUA_LOADLIBNAME, luaopen_package}, 45 | {LUA_COLIBNAME, luaopen_coroutine}, 46 | {LUA_TABLIBNAME, luaopen_table}, 47 | {LUA_IOLIBNAME, luaopen_io}, 48 | {LUA_OSLIBNAME, luaopen_os}, 49 | {LUA_STRLIBNAME, luaopen_string}, 50 | {LUA_MATHLIBNAME, luaopen_math}, 51 | {LUA_DBLIBNAME, luaopen_debug}, 52 | {NULL, NULL} 53 | }; 54 | 55 | 56 | LUALIB_API void luaL_openlibs (lua_State *L) { 57 | const luaL_Reg *lib; 58 | /* "require" functions from 'loadedlibs' and set results to global table */ 59 | for (lib = loadedlibs; lib->func; lib++) { 60 | luaL_requiref(L, lib->name, lib->func, 1); 61 | lua_pop(L, 1); /* remove lib */ 62 | } 63 | } 64 | 65 | -------------------------------------------------------------------------------- /src/lua/ljumptab.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ljumptab.h $ 3 | ** Jump Table for the Lua interpreter 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #undef vmdispatch 9 | #undef vmcase 10 | #undef vmbreak 11 | 12 | #define vmdispatch(x) goto *disptab[x]; 13 | 14 | #define vmcase(l) L_##l: 15 | 16 | #define vmbreak vmfetch(); vmdispatch(GET_OPCODE(i)); 17 | 18 | 19 | static const void *const disptab[NUM_OPCODES] = { 20 | 21 | #if 0 22 | ** you can update the following list with this command: 23 | ** 24 | ** sed -n '/^OP_/\!d; s/OP_/\&\&L_OP_/ ; s/,.*/,/ ; s/\/.*// ; p' lopcodes.h 25 | ** 26 | #endif 27 | 28 | &&L_OP_MOVE, 29 | &&L_OP_LOADI, 30 | &&L_OP_LOADF, 31 | &&L_OP_LOADK, 32 | &&L_OP_LOADKX, 33 | &&L_OP_LOADFALSE, 34 | &&L_OP_LFALSESKIP, 35 | &&L_OP_LOADTRUE, 36 | &&L_OP_LOADNIL, 37 | &&L_OP_GETUPVAL, 38 | &&L_OP_SETUPVAL, 39 | &&L_OP_GETTABUP, 40 | &&L_OP_GETTABLE, 41 | &&L_OP_GETI, 42 | &&L_OP_GETFIELD, 43 | &&L_OP_SETTABUP, 44 | &&L_OP_SETTABLE, 45 | &&L_OP_SETI, 46 | &&L_OP_SETFIELD, 47 | &&L_OP_NEWTABLE, 48 | &&L_OP_SELF, 49 | &&L_OP_ADDI, 50 | &&L_OP_ADDK, 51 | &&L_OP_SUBK, 52 | &&L_OP_MULK, 53 | &&L_OP_MODK, 54 | &&L_OP_POWK, 55 | &&L_OP_DIVK, 56 | &&L_OP_IDIVK, 57 | &&L_OP_BANDK, 58 | &&L_OP_BORK, 59 | &&L_OP_BXORK, 60 | &&L_OP_SHRI, 61 | &&L_OP_SHLI, 62 | &&L_OP_ADD, 63 | &&L_OP_SUB, 64 | &&L_OP_MUL, 65 | &&L_OP_MOD, 66 | &&L_OP_POW, 67 | &&L_OP_DIV, 68 | &&L_OP_IDIV, 69 | &&L_OP_BAND, 70 | &&L_OP_BOR, 71 | &&L_OP_BXOR, 72 | &&L_OP_SHL, 73 | &&L_OP_SHR, 74 | &&L_OP_MMBIN, 75 | &&L_OP_MMBINI, 76 | &&L_OP_MMBINK, 77 | &&L_OP_UNM, 78 | &&L_OP_BNOT, 79 | &&L_OP_NOT, 80 | &&L_OP_LEN, 81 | &&L_OP_CONCAT, 82 | &&L_OP_CLOSE, 83 | &&L_OP_TBC, 84 | &&L_OP_JMP, 85 | &&L_OP_EQ, 86 | &&L_OP_LT, 87 | &&L_OP_LE, 88 | &&L_OP_EQK, 89 | &&L_OP_EQI, 90 | &&L_OP_LTI, 91 | &&L_OP_LEI, 92 | &&L_OP_GTI, 93 | &&L_OP_GEI, 94 | &&L_OP_TEST, 95 | &&L_OP_TESTSET, 96 | &&L_OP_CALL, 97 | &&L_OP_TAILCALL, 98 | &&L_OP_RETURN, 99 | &&L_OP_RETURN0, 100 | &&L_OP_RETURN1, 101 | &&L_OP_FORLOOP, 102 | &&L_OP_FORPREP, 103 | &&L_OP_TFORPREP, 104 | &&L_OP_TFORCALL, 105 | &&L_OP_TFORLOOP, 106 | &&L_OP_SETLIST, 107 | &&L_OP_CLOSURE, 108 | &&L_OP_VARARG, 109 | &&L_OP_VARARGPREP, 110 | &&L_OP_EXTRAARG 111 | 112 | }; 113 | -------------------------------------------------------------------------------- /src/lua/lopnames.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lopnames.h $ 3 | ** Opcode names 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #if !defined(lopnames_h) 8 | #define lopnames_h 9 | 10 | #include 11 | 12 | 13 | /* ORDER OP */ 14 | 15 | static const char *const opnames[] = { 16 | "MOVE", 17 | "LOADI", 18 | "LOADF", 19 | "LOADK", 20 | "LOADKX", 21 | "LOADFALSE", 22 | "LFALSESKIP", 23 | "LOADTRUE", 24 | "LOADNIL", 25 | "GETUPVAL", 26 | "SETUPVAL", 27 | "GETTABUP", 28 | "GETTABLE", 29 | "GETI", 30 | "GETFIELD", 31 | "SETTABUP", 32 | "SETTABLE", 33 | "SETI", 34 | "SETFIELD", 35 | "NEWTABLE", 36 | "SELF", 37 | "ADDI", 38 | "ADDK", 39 | "SUBK", 40 | "MULK", 41 | "MODK", 42 | "POWK", 43 | "DIVK", 44 | "IDIVK", 45 | "BANDK", 46 | "BORK", 47 | "BXORK", 48 | "SHRI", 49 | "SHLI", 50 | "ADD", 51 | "SUB", 52 | "MUL", 53 | "MOD", 54 | "POW", 55 | "DIV", 56 | "IDIV", 57 | "BAND", 58 | "BOR", 59 | "BXOR", 60 | "SHL", 61 | "SHR", 62 | "MMBIN", 63 | "MMBINI", 64 | "MMBINK", 65 | "UNM", 66 | "BNOT", 67 | "NOT", 68 | "LEN", 69 | "CONCAT", 70 | "CLOSE", 71 | "TBC", 72 | "JMP", 73 | "EQ", 74 | "LT", 75 | "LE", 76 | "EQK", 77 | "EQI", 78 | "LTI", 79 | "LEI", 80 | "GTI", 81 | "GEI", 82 | "TEST", 83 | "TESTSET", 84 | "CALL", 85 | "TAILCALL", 86 | "RETURN", 87 | "RETURN0", 88 | "RETURN1", 89 | "FORLOOP", 90 | "FORPREP", 91 | "TFORPREP", 92 | "TFORCALL", 93 | "TFORLOOP", 94 | "SETLIST", 95 | "CLOSURE", 96 | "VARARG", 97 | "VARARGPREP", 98 | "EXTRAARG", 99 | NULL 100 | }; 101 | 102 | #endif 103 | 104 | -------------------------------------------------------------------------------- /src/lua/lprefix.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lprefix.h $ 3 | ** Definitions for Lua code that must come before any other header file 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lprefix_h 8 | #define lprefix_h 9 | 10 | 11 | /* 12 | ** Allows POSIX/XSI stuff 13 | */ 14 | #if !defined(LUA_USE_C89) /* { */ 15 | 16 | #if !defined(_XOPEN_SOURCE) 17 | #define _XOPEN_SOURCE 600 18 | #elif _XOPEN_SOURCE == 0 19 | #undef _XOPEN_SOURCE /* use -D_XOPEN_SOURCE=0 to undefine it */ 20 | #endif 21 | 22 | /* 23 | ** Allows manipulation of large files in gcc and some other compilers 24 | */ 25 | #if !defined(LUA_32BITS) && !defined(_FILE_OFFSET_BITS) 26 | #define _LARGEFILE_SOURCE 1 27 | #define _FILE_OFFSET_BITS 64 28 | #endif 29 | 30 | #endif /* } */ 31 | 32 | 33 | /* 34 | ** Windows stuff 35 | */ 36 | #if defined(_WIN32) /* { */ 37 | 38 | #if !defined(_CRT_SECURE_NO_WARNINGS) 39 | #define _CRT_SECURE_NO_WARNINGS /* avoid warnings about ISO C functions */ 40 | #endif 41 | 42 | #endif /* } */ 43 | 44 | #endif 45 | 46 | -------------------------------------------------------------------------------- /src/lua/lstring.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstring.h $ 3 | ** String table (keep all strings handled by Lua) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lstring_h 8 | #define lstring_h 9 | 10 | #include "lgc.h" 11 | #include "lobject.h" 12 | #include "lstate.h" 13 | 14 | 15 | /* 16 | ** Memory-allocation error message must be preallocated (it cannot 17 | ** be created after memory is exhausted) 18 | */ 19 | #define MEMERRMSG "not enough memory" 20 | 21 | 22 | /* 23 | ** Size of a TString: Size of the header plus space for the string 24 | ** itself (including final '\0'). 25 | */ 26 | #define sizelstring(l) (offsetof(TString, contents) + ((l) + 1) * sizeof(char)) 27 | 28 | #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ 29 | (sizeof(s)/sizeof(char))-1)) 30 | 31 | 32 | /* 33 | ** test whether a string is a reserved word 34 | */ 35 | #define isreserved(s) ((s)->tt == LUA_VSHRSTR && (s)->extra > 0) 36 | 37 | 38 | /* 39 | ** equality for short strings, which are always internalized 40 | */ 41 | #define eqshrstr(a,b) check_exp((a)->tt == LUA_VSHRSTR, (a) == (b)) 42 | 43 | 44 | LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); 45 | LUAI_FUNC unsigned int luaS_hashlongstr (TString *ts); 46 | LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); 47 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); 48 | LUAI_FUNC void luaS_clearcache (global_State *g); 49 | LUAI_FUNC void luaS_init (lua_State *L); 50 | LUAI_FUNC void luaS_remove (lua_State *L, TString *ts); 51 | LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, int nuvalue); 52 | LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); 53 | LUAI_FUNC TString *luaS_new (lua_State *L, const char *str); 54 | LUAI_FUNC TString *luaS_createlngstrobj (lua_State *L, size_t l); 55 | 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /src/lua/ltable.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltable.h $ 3 | ** Lua tables (hash) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ltable_h 8 | #define ltable_h 9 | 10 | #include "lobject.h" 11 | 12 | 13 | #define gnode(t,i) (&(t)->node[i]) 14 | #define gval(n) (&(n)->i_val) 15 | #define gnext(n) ((n)->u.next) 16 | 17 | 18 | /* 19 | ** Clear all bits of fast-access metamethods, which means that the table 20 | ** may have any of these metamethods. (First access that fails after the 21 | ** clearing will set the bit again.) 22 | */ 23 | #define invalidateTMcache(t) ((t)->flags &= ~maskflags) 24 | 25 | 26 | /* true when 't' is using 'dummynode' as its hash part */ 27 | #define isdummy(t) ((t)->lastfree == NULL) 28 | 29 | 30 | /* allocated size for hash nodes */ 31 | #define allocsizenode(t) (isdummy(t) ? 0 : sizenode(t)) 32 | 33 | 34 | /* returns the Node, given the value of a table entry */ 35 | #define nodefromval(v) cast(Node *, (v)) 36 | 37 | 38 | LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); 39 | LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, 40 | TValue *value); 41 | LUAI_FUNC const TValue *luaH_getshortstr (Table *t, TString *key); 42 | LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); 43 | LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); 44 | LUAI_FUNC void luaH_newkey (lua_State *L, Table *t, const TValue *key, 45 | TValue *value); 46 | LUAI_FUNC void luaH_set (lua_State *L, Table *t, const TValue *key, 47 | TValue *value); 48 | LUAI_FUNC void luaH_finishset (lua_State *L, Table *t, const TValue *key, 49 | const TValue *slot, TValue *value); 50 | LUAI_FUNC Table *luaH_new (lua_State *L); 51 | LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize, 52 | unsigned int nhsize); 53 | LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize); 54 | LUAI_FUNC void luaH_free (lua_State *L, Table *t); 55 | LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); 56 | LUAI_FUNC lua_Unsigned luaH_getn (Table *t); 57 | LUAI_FUNC unsigned int luaH_realasize (const Table *t); 58 | 59 | 60 | #if defined(LUA_DEBUG) 61 | LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); 62 | LUAI_FUNC int luaH_isdummy (const Table *t); 63 | #endif 64 | 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /src/lua/lua.hpp: -------------------------------------------------------------------------------- 1 | // lua.hpp 2 | // Lua header files for C++ 3 | // <> not supplied automatically because Lua also compiles as C++ 4 | 5 | extern "C" { 6 | #include "lua.h" 7 | #include "lualib.h" 8 | #include "lauxlib.h" 9 | } 10 | -------------------------------------------------------------------------------- /src/lua/lualib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lualib.h $ 3 | ** Lua standard libraries 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lualib_h 9 | #define lualib_h 10 | 11 | #include "lua.h" 12 | 13 | 14 | /* version suffix for environment variable names */ 15 | #define LUA_VERSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR 16 | 17 | 18 | LUAMOD_API int (luaopen_base) (lua_State *L); 19 | 20 | #define LUA_COLIBNAME "coroutine" 21 | LUAMOD_API int (luaopen_coroutine) (lua_State *L); 22 | 23 | #define LUA_TABLIBNAME "table" 24 | LUAMOD_API int (luaopen_table) (lua_State *L); 25 | 26 | #define LUA_IOLIBNAME "io" 27 | LUAMOD_API int (luaopen_io) (lua_State *L); 28 | 29 | #define LUA_OSLIBNAME "os" 30 | LUAMOD_API int (luaopen_os) (lua_State *L); 31 | 32 | #define LUA_STRLIBNAME "string" 33 | LUAMOD_API int (luaopen_string) (lua_State *L); 34 | 35 | #define LUA_MATHLIBNAME "math" 36 | LUAMOD_API int (luaopen_math) (lua_State *L); 37 | 38 | #define LUA_DBLIBNAME "debug" 39 | LUAMOD_API int (luaopen_debug) (lua_State *L); 40 | 41 | #define LUA_LOADLIBNAME "package" 42 | LUAMOD_API int (luaopen_package) (lua_State *L); 43 | 44 | 45 | /* open all previous libraries */ 46 | LUALIB_API void (luaL_openlibs) (lua_State *L); 47 | 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /src/lua/lundump.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lundump.h $ 3 | ** load precompiled Lua chunks 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lundump_h 8 | #define lundump_h 9 | 10 | #include "llimits.h" 11 | #include "lobject.h" 12 | #include "lzio.h" 13 | 14 | 15 | /* data to catch conversion errors */ 16 | #define LUAC_DATA "\x19\x93\r\n\x1a\n" 17 | 18 | #define LUAC_INT 0x5678 19 | #define LUAC_NUM cast_num(370.5) 20 | 21 | /* 22 | ** Encode major-minor version in one byte, one nibble for each 23 | */ 24 | #define MYINT(s) (s[0]-'0') /* assume one-digit numerals */ 25 | #define LUAC_VERSION (MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR)) 26 | 27 | #define LUAC_FORMAT 0 /* this is the official format */ 28 | 29 | /* load one chunk; from lundump.c */ 30 | LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, const char* name); 31 | 32 | /* dump one chunk; from ldump.c */ 33 | LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, 34 | void* data, int strip); 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /src/lua/lzio.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lzio.c $ 3 | ** Buffered streams 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lzio_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "llimits.h" 18 | #include "lmem.h" 19 | #include "lstate.h" 20 | #include "lzio.h" 21 | 22 | 23 | int luaZ_fill (ZIO *z) { 24 | size_t size; 25 | lua_State *L = z->L; 26 | const char *buff; 27 | lua_unlock(L); 28 | buff = z->reader(L, z->data, &size); 29 | lua_lock(L); 30 | if (buff == NULL || size == 0) 31 | return EOZ; 32 | z->n = size - 1; /* discount char being returned */ 33 | z->p = buff; 34 | return cast_uchar(*(z->p++)); 35 | } 36 | 37 | 38 | void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { 39 | z->L = L; 40 | z->reader = reader; 41 | z->data = data; 42 | z->n = 0; 43 | z->p = NULL; 44 | } 45 | 46 | 47 | /* --------------------------------------------------------------- read --- */ 48 | size_t luaZ_read (ZIO *z, void *b, size_t n) { 49 | while (n) { 50 | size_t m; 51 | if (z->n == 0) { /* no bytes in buffer? */ 52 | if (luaZ_fill(z) == EOZ) /* try to read more */ 53 | return n; /* no more input; return number of missing bytes */ 54 | else { 55 | z->n++; /* luaZ_fill consumed first byte; put it back */ 56 | z->p--; 57 | } 58 | } 59 | m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ 60 | memcpy(b, z->p, m); 61 | z->n -= m; 62 | z->p += m; 63 | b = (char *)b + m; 64 | n -= m; 65 | } 66 | return 0; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /src/lua/lzio.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lzio.h $ 3 | ** Buffered streams 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lzio_h 9 | #define lzio_h 10 | 11 | #include "lua.h" 12 | 13 | #include "lmem.h" 14 | 15 | 16 | #define EOZ (-1) /* end of stream */ 17 | 18 | typedef struct Zio ZIO; 19 | 20 | #define zgetc(z) (((z)->n--)>0 ? cast_uchar(*(z)->p++) : luaZ_fill(z)) 21 | 22 | 23 | typedef struct Mbuffer { 24 | char *buffer; 25 | size_t n; 26 | size_t buffsize; 27 | } Mbuffer; 28 | 29 | #define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) 30 | 31 | #define luaZ_buffer(buff) ((buff)->buffer) 32 | #define luaZ_sizebuffer(buff) ((buff)->buffsize) 33 | #define luaZ_bufflen(buff) ((buff)->n) 34 | 35 | #define luaZ_buffremove(buff,i) ((buff)->n -= (i)) 36 | #define luaZ_resetbuffer(buff) ((buff)->n = 0) 37 | 38 | 39 | #define luaZ_resizebuffer(L, buff, size) \ 40 | ((buff)->buffer = luaM_reallocvchar(L, (buff)->buffer, \ 41 | (buff)->buffsize, size), \ 42 | (buff)->buffsize = size) 43 | 44 | #define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) 45 | 46 | 47 | LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, 48 | void *data); 49 | LUAI_FUNC size_t luaZ_read (ZIO* z, void *b, size_t n); /* read next n bytes */ 50 | 51 | 52 | 53 | /* --------- Private Part ------------------ */ 54 | 55 | struct Zio { 56 | size_t n; /* bytes still unread */ 57 | const char *p; /* current position in buffer */ 58 | lua_Reader reader; /* reader function */ 59 | void *data; /* additional data */ 60 | lua_State *L; /* Lua state (for reader) */ 61 | }; 62 | 63 | 64 | LUAI_FUNC int luaZ_fill (ZIO *z); 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /src/lua_util.c: -------------------------------------------------------------------------------- 1 | #include "lua_util.h" 2 | 3 | #include 4 | 5 | #include "lua/lauxlib.h" 6 | #include "lua/lualib.h" 7 | 8 | int util_msghandler(lua_State *L) 9 | { 10 | const char *msg = lua_tostring(L, 1); 11 | if (msg == NULL) /* is error object not a string? */ 12 | { 13 | if (luaL_callmeta(L, 1, "__tostring") && /* does it have a metamethod */ 14 | lua_type(L, -1) == LUA_TSTRING) /* that produces a string? */ 15 | { 16 | return 1; /* that is the message */ 17 | } 18 | else 19 | { 20 | msg = lua_pushfstring(L, "(error object is a %s value)", 21 | luaL_typename(L, 1)); 22 | } 23 | } 24 | luaL_traceback(L, L, msg, 1); /* append a standard traceback */ 25 | return 1; /* return the traceback */ 26 | } 27 | 28 | lua_State* util_create_minimal_lua_state(void) 29 | { 30 | lua_State* L = luaL_newstate(); 31 | if (L == NULL) 32 | { 33 | fprintf(stderr, "%s\n", "cannot create state: not enough memory"); 34 | exit(EXIT_FAILURE); 35 | } 36 | return L; 37 | } 38 | 39 | /* this is taken from lua/init.c, but the list of modules is modified, we don't need package for instance */ 40 | void _load_lualibs(lua_State *L) 41 | { 42 | static const luaL_Reg loadedlibs[] = { 43 | {LUA_GNAME, luaopen_base}, 44 | {LUA_LOADLIBNAME, luaopen_package}, 45 | //{LUA_COLIBNAME, luaopen_coroutine}, 46 | {LUA_TABLIBNAME, luaopen_table}, 47 | {LUA_IOLIBNAME, luaopen_io}, 48 | {LUA_OSLIBNAME, luaopen_os}, // replace os.exit and os.time, then this 'dependency' can also be removed 49 | {LUA_STRLIBNAME, luaopen_string}, 50 | {LUA_MATHLIBNAME, luaopen_math}, 51 | //{LUA_UTF8LIBNAME, luaopen_utf8}, 52 | {LUA_DBLIBNAME, luaopen_debug}, 53 | {NULL, NULL} 54 | }; 55 | 56 | const luaL_Reg *lib; 57 | /* "require" functions from 'loadedlibs' and set results to global table */ 58 | for (lib = loadedlibs; lib->func; lib++) { 59 | luaL_requiref(L, lib->name, lib->func, 1); 60 | lua_pop(L, 1); /* remove lib */ 61 | } 62 | } 63 | 64 | 65 | lua_State* util_create_basic_lua_state(void) 66 | { 67 | lua_State* L = util_create_minimal_lua_state(); 68 | _load_lualibs(L); 69 | return L; 70 | } 71 | 72 | -------------------------------------------------------------------------------- /src/lua_util.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_LUA_UTIL_H 2 | #define OPC_LUA_UTIL_H 3 | 4 | #include "lua/lua.h" 5 | 6 | int util_msghandler(lua_State *L); 7 | lua_State* util_create_minimal_lua_state(void); 8 | lua_State* util_create_basic_lua_state(void); 9 | 10 | #endif // OPC_LUA_UTIL_H 11 | -------------------------------------------------------------------------------- /src/lutil.c: -------------------------------------------------------------------------------- 1 | #include "lutil.h" 2 | 3 | #include "lpoint.h" 4 | 5 | struct simple_polygon* lutil_create_simple_polygon(lua_State* L, int idx) 6 | { 7 | lua_len(L, idx); 8 | size_t len = lua_tointeger(L, -1); 9 | lua_pop(L, 1); 10 | struct simple_polygon* result = simple_polygon_create(); 11 | for(size_t i = 1; i <= len; ++i) 12 | { 13 | lua_rawgeti(L, idx, i); 14 | struct lpoint* pt = lpoint_checkpoint(L, -1); 15 | simple_polygon_append(result, point_copy(lpoint_get(pt))); 16 | lua_pop(L, 1); 17 | } 18 | return result; 19 | } 20 | 21 | -------------------------------------------------------------------------------- /src/lutil.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_LUTIL_H 2 | #define OPC_LUTIL_H 3 | 4 | #include "lua/lua.h" 5 | 6 | #include "polygon.h" 7 | 8 | struct simple_polygon* lutil_create_simple_polygon(lua_State* L, int idx); 9 | 10 | #endif /* OPC_LUTIL_H */ 11 | -------------------------------------------------------------------------------- /src/main.api_help.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_MAIN_API_H 2 | #define OPC_MAIN_API_H 3 | 4 | void main_API_help(const char* funcname); 5 | void main_API_search(const char* name); 6 | void main_API_list(void); 7 | void main_API_create_latex_doc(void); 8 | 9 | #endif // OPC_MAIN_API_H 10 | -------------------------------------------------------------------------------- /src/main.api_help/aux.c: -------------------------------------------------------------------------------- 1 | 2 | /* FIXME: aux.all_of */ 3 | /* FIXME: aux.any_of */ 4 | /* FIXME: aux.assert_one_of */ 5 | /* FIXME: aux.clone_shallow */ 6 | /* FIXME: aux.find */ 7 | /* FIXME: aux.find_predicate */ 8 | /* FIXME: aux.gcd */ 9 | /* FIXME: aux.make_even */ 10 | /* FIXME: aux.pop_top_directory */ 11 | /* FIXME: aux.shuffle */ 12 | /* FIXME: aux.split_path */ 13 | /* FIXME: aux.strgsplit */ 14 | /* FIXME: aux.strsplit */ 15 | /* FIXME: aux.sum */ 16 | /* FIXME: aux.tabgcd */ 17 | /* FIXME: aux.tprint */ 18 | -------------------------------------------------------------------------------- /src/main.api_help/curve.c: -------------------------------------------------------------------------------- 1 | /* curve.arcto, */ 2 | { 3 | struct parameter parameters[] = { 4 | { "startangle", NUMBER, NULL, "start angle of the line segment" }, 5 | { "endangle", NUMBER, NULL, "end angle of the line segment" }, 6 | { "radius", INTEGER, NULL, "radius of the line segment" }, 7 | { "clockwise", BOOLEAN, NULL, "flag if arc is drawn clock-wise or counter-clock-wise" } 8 | }; 9 | vector_append(entries, _make_api_entry( 10 | "arcto", 11 | MODULE_CURVE, 12 | // help text 13 | "create an arc segment for a curve", 14 | // example 15 | "geometry.curve(cell, generics.metal(1), point.create(0, 0), {\n" 16 | " curve.arcto(180, 0, 1000, true),\n" 17 | "}, grid, allow45)\n" 18 | , 19 | parameters, 20 | sizeof(parameters) / sizeof(parameters[0]) 21 | )); 22 | } 23 | 24 | /* curve.cubicto */ 25 | { 26 | struct parameter parameters[] = { 27 | { "ctp1", POINT, NULL, "first control point" }, 28 | { "ctp2", POINT, NULL, "second control point" }, 29 | { "endpt", POINT, NULL, "destination point of the cubic bezier segment" } 30 | }; 31 | vector_append(entries, _make_api_entry( 32 | "cubicto", 33 | MODULE_CURVE, 34 | // help text 35 | "create a cubic bezier segment for a curve", 36 | // example 37 | "geometry.curve(cell, generics.metal(1), point.create(0, 0), {\n" 38 | " curve.cubicto(point.create(0, 500), point.create(500, 500), point.create(500, 0)),\n" 39 | "}, grid, allow45)\n" 40 | , 41 | parameters, 42 | sizeof(parameters) / sizeof(parameters[0]) 43 | )); 44 | } 45 | 46 | /* curve.lineto, */ 47 | { 48 | struct parameter parameters[] = { 49 | { "point", POINT, NULL, "destination point of the line segment" } 50 | }; 51 | vector_append(entries, _make_api_entry( 52 | "lineto", 53 | MODULE_CURVE, 54 | // help text 55 | "create a line segment for a curve", 56 | // example 57 | "geometry.curve(cell, generics.metal(1), point.create(0, 0), {\n" 58 | " curve.lineto(point.create(1000, 1000)),\n" 59 | "}, grid, allow45)\n" 60 | , 61 | parameters, 62 | sizeof(parameters) / sizeof(parameters[0]) 63 | )); 64 | } 65 | 66 | -------------------------------------------------------------------------------- /src/main.api_help/graphics.c: -------------------------------------------------------------------------------- 1 | /* 2 | graphics.circle 3 | graphics.coarse_circle 4 | graphics.ellipse 5 | graphics.quartercircle 6 | graphics.quarterellipse 7 | */ 8 | -------------------------------------------------------------------------------- /src/main.api_help/placer.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | FIXME: 4 | placer.place_classic 5 | placer.place_nonoverlapping 6 | placer.place_simulated_annealing 7 | */ 8 | -------------------------------------------------------------------------------- /src/main.api_help/router.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | FIXME: 4 | router.initialize 5 | router.resolve_routes 6 | router.route 7 | */ 8 | -------------------------------------------------------------------------------- /src/main.api_help/routing.c: -------------------------------------------------------------------------------- 1 | /* routing.legalize */ // FIXME: legalize 2 | { 3 | struct parameter parameters[] = { 4 | 5 | }; 6 | vector_append(entries, _make_api_entry( 7 | "legalize", 8 | MODULE_ROUTING, 9 | "", 10 | "", 11 | parameters, 12 | sizeof(parameters) / sizeof(parameters[0]) 13 | )); 14 | } 15 | 16 | /* routing.route */ // FIXME: route 17 | { 18 | struct parameter parameters[] = { 19 | 20 | }; 21 | vector_append(entries, _make_api_entry( 22 | "route", 23 | MODULE_ROUTING, 24 | "", 25 | "", 26 | parameters, 27 | sizeof(parameters) / sizeof(parameters[0]) 28 | )); 29 | } 30 | 31 | /* 32 | FIXME: 33 | routing.basic 34 | */ 35 | -------------------------------------------------------------------------------- /src/main.cell.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_MAIN_CELL_H 2 | #define OPC_MAIN_CELL_H 3 | 4 | #include "hashmap.h" 5 | #include "cmdoptions.h" 6 | 7 | void main_list_cells_cellpaths(struct cmdoptions* cmdoptions, struct hashmap* config); 8 | void main_list_cell_parameters(struct cmdoptions* cmdoptions, struct hashmap* config); 9 | void main_list_cell_anchors(struct cmdoptions* cmdoptions, struct hashmap* config); 10 | int main_create_and_export_cell(struct cmdoptions* cmdoptions, struct hashmap* config, int iscellscript); 11 | 12 | #endif // OPC_MAIN_CELL_H 13 | -------------------------------------------------------------------------------- /src/main.functions.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_MAIN_FUNCTIONS_H 2 | #define OPC_MAIN_FUNCTIONS_H 3 | 4 | #include "lua/lua.h" 5 | 6 | lua_State* main_create_and_initialize_lua(void); 7 | int main_lua_pcall(lua_State* L, int nargs, int nresults); 8 | int main_call_lua_program(lua_State* L, const char* filename); 9 | int main_call_lua_program_from_buffer(lua_State* L, const unsigned char* data, size_t len, const char* name); 10 | int main_load_module(lua_State* L, const unsigned char* data, size_t len, const char* name, const char* chunkname); 11 | 12 | #endif // OPC_MAIN_FUNCTIONS_H 13 | -------------------------------------------------------------------------------- /src/main.gds.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_MAIN_GDS_H 2 | #define OPC_MAIN_GDS_H 3 | 4 | #include "cmdoptions.h" 5 | 6 | void main_gds_show_data(struct cmdoptions* cmdoptions); 7 | void main_gds_show_cell_hierarchy(struct cmdoptions* cmdoptions); 8 | void main_gds_show_cell_definitions(struct cmdoptions* cmdoptions); 9 | void main_gds_read(struct cmdoptions* cmdoptions); 10 | 11 | #endif // OPC_MAIN_GDS_H 12 | -------------------------------------------------------------------------------- /src/main.tutorial.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_MAIN_TUTORIAL_H 2 | #define OPC_MAIN_TUTORIAL_H 3 | 4 | void main_generate_tutorial(void); 5 | 6 | #endif /* OPC_MAIN_TUTORIAL_H */ 7 | -------------------------------------------------------------------------------- /src/main.verilog.c: -------------------------------------------------------------------------------- 1 | #include "main.verilog.h" 2 | 3 | #include "lua/lua.h" 4 | 5 | #include 6 | 7 | #include "lua/lauxlib.h" 8 | 9 | #include "filesystem.h" 10 | #include "lplacement.h" 11 | #include "lplacer.h" 12 | #include "lrouter.h" 13 | #include "lua_util.h" 14 | #include "modulemanager.h" 15 | #include "util.h" 16 | #include "util_cmodule.h" 17 | 18 | #include "main.functions.h" 19 | 20 | void main_verilog_import(const char* scriptname, const struct const_vector* args) 21 | { 22 | lua_State* L = util_create_basic_lua_state(); 23 | open_lutil_cmodule_lib(L); 24 | module_load_globals(L); 25 | module_load_check(L); 26 | module_load_aux(L); 27 | module_load_util(L); 28 | module_load_verilog(L); 29 | module_load_verilogprocessor(L); 30 | open_lplacer_lib(L); 31 | open_lplacement_lib(L); 32 | module_load_placement(L); 33 | open_lrouter_lib(L); 34 | module_load_routing(L); 35 | open_lfilesystem_lib(L); 36 | module_load_generator(L); 37 | 38 | // script args 39 | lua_newtable(L); 40 | for(unsigned int i = 0; i < const_vector_size(args); ++i) 41 | { 42 | lua_pushstring(L, const_vector_get(args, i)); 43 | lua_rawseti(L, -2, i + 1); 44 | } 45 | lua_setglobal(L, "args"); 46 | 47 | main_call_lua_program(L, scriptname); 48 | lua_close(L); 49 | } 50 | 51 | -------------------------------------------------------------------------------- /src/main.verilog.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_MAIN_VERILOG_H 2 | #define OPC_MAIN_VERILOG_H 3 | 4 | #include "vector.h" 5 | 6 | void main_verilog_import(const char* filename, const struct const_vector* args); 7 | 8 | #endif // OPC_MAIN_VERILOG_H 9 | -------------------------------------------------------------------------------- /src/math.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_MATH_H 2 | #define OPC_MATH_H 3 | 4 | #include 5 | #ifndef M_PI 6 | #define M_PI 3.14159265358979323846 7 | #endif 8 | 9 | #endif /* OPC_MATH_H */ 10 | -------------------------------------------------------------------------------- /src/modules/check.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | local funcnamestack = {} 4 | 5 | function M.set_next_function_name(funcname) 6 | funcnamestack[#funcnamestack + 1] = funcname 7 | end 8 | 9 | function M.reset_function_name(funcname) 10 | funcnamestack[#funcnamestack] = nil 11 | end 12 | 13 | function M.arg(index, argname, typename, arg) 14 | if not arg then 15 | error(string.format("%s expected a %s as argument #%d ('%s'), got nil", funcnamestack[#funcnamestack], typename, index, argname)) 16 | end 17 | if type(arg) ~= typename then 18 | error(string.format("%s expected a %s as argument #%d ('%s'), got %s", funcnamestack[#funcnamestack], typename, index, argname, type(arg))) 19 | end 20 | end 21 | 22 | function M.arg_optional(index, argname, typename, arg) 23 | if arg and type(arg) ~= typename then 24 | error(string.format("%s expected a (optional) %s as argument #%d ('%s'), got %s", funcnamestack[#funcnamestack], typename, index, argname, type(arg))) 25 | end 26 | end 27 | 28 | function M.arg_func(index, argname, typename, arg, func) 29 | if not arg then 30 | error(string.format("%s expected a %s as argument #%d ('%s'), got nil", funcnamestack[#funcnamestack], typename, index, argname)) 31 | end 32 | if not func(arg) then 33 | error(string.format("%s expected a %s as argument #%d ('%s'), got %s", funcnamestack[#funcnamestack], typename, index, argname, type(arg))) 34 | end 35 | end 36 | 37 | return M 38 | -------------------------------------------------------------------------------- /src/modules/load.lua: -------------------------------------------------------------------------------- 1 | -- luacheck: ignore _get_reader _generic_load _load_module load 2 | function _get_reader(filename) 3 | local file = io.open(filename, "r") 4 | if not file then 5 | return nil, string.format("could not open file '%s'", filename) 6 | end 7 | local chunksize = 1000 8 | return function() 9 | return file:read(chunksize) 10 | end 11 | end 12 | 13 | function _generic_load(reader, chunkname, synerrmsg, semerrmsg, env) 14 | env = env or _ENV 15 | local func, msg = load(reader, chunkname, "t", env) 16 | 17 | if not func then 18 | if synerrmsg then 19 | error(string.format("%s: %s", synerrmsg, msg), 0) 20 | else 21 | error(msg, 0) 22 | end 23 | end 24 | 25 | local status, chunk = pcall(func) 26 | if not status then 27 | if semerrmsg then 28 | error(string.format("%s: %s", semerrmsg, chunk), 0) 29 | else 30 | error(chunk, 0) 31 | end 32 | end 33 | 34 | return chunk 35 | end 36 | 37 | function _dofile(reader, chunkname, synerrmsg, env) 38 | env = env or _ENV 39 | local func, msg = load(reader, chunkname, "t", env) 40 | 41 | if not func then 42 | if synerrmsg then 43 | error(string.format("%s: %s", synerrmsg, msg), 0) 44 | else 45 | error(msg, 0) 46 | end 47 | end 48 | 49 | return func() 50 | end 51 | 52 | -------------------------------------------------------------------------------- /src/modules/stack.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | local meta = {} 4 | meta.__index = meta 5 | 6 | function M.create() 7 | local self = {} 8 | setmetatable(self, meta) 9 | return self 10 | end 11 | 12 | function meta.push(self, value) 13 | table.insert(self, value) 14 | end 15 | 16 | function meta.top(self) 17 | return self[#self] 18 | end 19 | 20 | function meta.pop(self) 21 | table.remove(self) 22 | end 23 | 24 | function meta.peek(self) 25 | return #self > 0 26 | end 27 | 28 | return M 29 | -------------------------------------------------------------------------------- /src/pcell.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_PCELL_H 2 | #define OPC_PCELL_H 3 | 4 | #include "lua/lua.h" 5 | 6 | #include "object.h" 7 | #include "technology.h" 8 | #include "vector.h" 9 | 10 | struct pcell_state; 11 | 12 | typedef int (*cell_layout_func)(struct pcell_state* pcell_state, struct technology_state* techstate, struct object* cell); 13 | 14 | struct pcell_state* pcell_initialize_state(void); 15 | void pcell_destroy_state(struct pcell_state* state); 16 | 17 | struct object* pcell_create_layout(const char* cellname, struct technology_state* techstate, struct pcell_state* pcell_state); 18 | 19 | void pcell_prepend_cellpath(struct pcell_state*, const char* path); 20 | void pcell_append_cellpath(struct pcell_state*, const char* path); 21 | 22 | void pcell_append_pfile(struct pcell_state* pcell_state, const char* pfile); 23 | 24 | void pcell_list_cellpaths(const struct pcell_state* pcell_state); 25 | void pcell_list_cells(struct pcell_state* pcell_state, const char* listformat); 26 | void pcell_list_parameters(struct pcell_state* pcell_state, struct technology_state* techstate, const char* cellname, const char* parametersformat, struct const_vector* parameternames); 27 | void pcell_list_anchors(struct pcell_state* pcell_state, const char* cellname, const char* anchorsformat, struct const_vector* anchornames); 28 | 29 | int open_lpcell_lib(lua_State* L); 30 | 31 | void pcell_enable_debug(struct pcell_state* pcell_state); 32 | void pcell_enable_dprint(struct pcell_state* pcell_state); 33 | void pcell_set_dprint_target(struct pcell_state* pcell_state, const char* filename); 34 | 35 | struct object* pcell_create_layout_from_script(struct pcell_state* pcell_state, struct technology_state* techstate, const char* cellname, const char* name, struct const_vector* cellargs, const char* cellenvfilename); 36 | struct object* pcell_create_layout_env(struct pcell_state* pcell_state, struct technology_state* techstate, const char* cellname, const char* toplevelname, const char* cellenvfilename); 37 | 38 | #endif // OPC_PCELL_H 39 | -------------------------------------------------------------------------------- /src/point.c: -------------------------------------------------------------------------------- 1 | #include "point.h" 2 | 3 | #include 4 | 5 | struct point* point_create(coordinate_t x, coordinate_t y) 6 | { 7 | struct point* pt = malloc(sizeof(*pt)); 8 | pt->x = x; 9 | pt->y = y; 10 | return pt; 11 | } 12 | 13 | void point_destroy(void* pt) 14 | { 15 | free(pt); 16 | } 17 | 18 | void* point_copy(const void* v) 19 | { 20 | const struct point* pt = v; 21 | struct point* new = point_create(pt->x, pt->y); 22 | return new; 23 | } 24 | 25 | inline coordinate_t point_getx(const struct point* pt) 26 | { 27 | return pt->x; 28 | } 29 | 30 | inline coordinate_t point_gety(const struct point* pt) 31 | { 32 | return pt->y; 33 | } 34 | 35 | void point_translate(struct point* pt, coordinate_t x, coordinate_t y) 36 | { 37 | pt->x += x; 38 | pt->y += y; 39 | } 40 | 41 | struct point* point_create_minimum(void) 42 | { 43 | return point_create(COORDINATE_MIN, COORDINATE_MIN); 44 | } 45 | 46 | struct point* point_create_maximum(void) 47 | { 48 | return point_create(COORDINATE_MAX, COORDINATE_MAX); 49 | } 50 | 51 | void point_update_minimum(struct point** min, const struct point* pt) 52 | { 53 | if(pt->x < (*min)->x) 54 | { 55 | (*min)->x = pt->x; 56 | } 57 | if(pt->y < (*min)->y) 58 | { 59 | (*min)->y = pt->y; 60 | } 61 | } 62 | 63 | void point_update_maximum(struct point** max, const struct point* pt) 64 | { 65 | if(pt->x > (*max)->x) 66 | { 67 | (*max)->x = pt->x; 68 | } 69 | if(pt->y > (*max)->y) 70 | { 71 | (*max)->y = pt->y; 72 | } 73 | } 74 | 75 | coordinate_t point_xdifference(const struct point* pt1, const struct point* pt2) 76 | { 77 | return pt1->x - pt2->x; 78 | } 79 | 80 | coordinate_t point_ydifference(const struct point* pt1, const struct point* pt2) 81 | { 82 | return pt1->y - pt2->y; 83 | } 84 | -------------------------------------------------------------------------------- /src/point.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_POINT_H 2 | #define OPC_POINT_H 3 | 4 | #include 5 | #include 6 | 7 | typedef long long int coordinate_t; 8 | typedef unsigned long long int ucoordinate_t; 9 | #define COORDINATE_MAX LLONG_MAX 10 | #define COORDINATE_MIN LLONG_MIN 11 | #define UCOORDINATE_MAX ULLONG_MAX 12 | #define UCOORDINATE_MIN 0 13 | #define coordinate_abs llabs 14 | 15 | struct point { 16 | coordinate_t x; 17 | coordinate_t y; 18 | }; 19 | 20 | struct point* point_create(coordinate_t x, coordinate_t y); 21 | void point_destroy(void* pt); // void*, otherwise we get a warning while destroying vectors 22 | void* point_copy(const void* pt); 23 | 24 | coordinate_t point_getx(const struct point* pt); 25 | coordinate_t point_gety(const struct point* pt); 26 | 27 | void point_translate(struct point* pt, coordinate_t x, coordinate_t y); 28 | 29 | // min/max calculations 30 | struct point* point_create_minimum(void); 31 | struct point* point_create_maximum(void); 32 | void point_update_minimum(struct point** min, const struct point* pt); 33 | void point_update_maximum(struct point** max, const struct point* pt); 34 | 35 | coordinate_t point_xdifference(const struct point* pt1, const struct point* pt2); 36 | coordinate_t point_ydifference(const struct point* pt1, const struct point* pt2); 37 | 38 | #endif // OPC_POINT_H 39 | -------------------------------------------------------------------------------- /src/postprocess.c: -------------------------------------------------------------------------------- 1 | #include "postprocess.h" 2 | 3 | #include 4 | 5 | #include "vector.h" 6 | #include "union.h" 7 | 8 | static void _merge_shapes(struct object* object, struct technology_state* techstate) 9 | { 10 | struct layer_iterator* it = layer_iterator_create(techstate); 11 | while(layer_iterator_is_valid(it)) 12 | { 13 | const struct generics* layer = layer_iterator_get(it); 14 | struct vector* rectangles = vector_create(32, NULL); 15 | for(int j = object_get_shapes_size(object) - 1; j >= 0; --j) 16 | { 17 | struct shape* S = object_get_shape(object, j); 18 | if(shape_is_rectangle(S) && shape_get_layer(S) == layer) 19 | { 20 | vector_append(rectangles, S); 21 | object_disown_shape(object, j); 22 | } 23 | } 24 | if(vector_size(rectangles) > 1) 25 | { 26 | union_rectangle_all(rectangles); 27 | } 28 | for(unsigned int i = 0; i < vector_size(rectangles); ++i) 29 | { 30 | object_add_raw_shape(object, vector_get(rectangles, i)); 31 | } 32 | vector_destroy(rectangles); 33 | layer_iterator_next(it); 34 | } 35 | layer_iterator_destroy(it); 36 | } 37 | 38 | void postprocess_merge_shapes(struct object* object, struct technology_state* techstate) 39 | { 40 | _merge_shapes(object, techstate); 41 | } 42 | 43 | void postprocess_remove_layer_shapes_flat(struct object* object, const struct generics* layer) 44 | { 45 | for(int i = object_get_shapes_size(object) - 1; i >= 0; --i) 46 | { 47 | struct shape* S = object_get_shape(object, i); 48 | if(shape_get_layer(S) == layer) 49 | { 50 | object_remove_shape(object, i); 51 | } 52 | } 53 | } 54 | 55 | void postprocess_remove_layer_shapes(struct object* object, const struct generics* layer) 56 | { 57 | postprocess_remove_layer_shapes_flat(object, layer); 58 | struct mutable_reference_iterator* ref_it = object_create_mutable_reference_iterator(object); 59 | while(mutable_reference_iterator_is_valid(ref_it)) 60 | { 61 | struct object* reference = mutable_reference_iterator_get(ref_it); 62 | postprocess_remove_layer_shapes(reference, layer); 63 | mutable_reference_iterator_next(ref_it); 64 | } 65 | } 66 | 67 | -------------------------------------------------------------------------------- /src/postprocess.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_POSTPROCESS_H 2 | #define OPC_POSTPROCESS_H 3 | 4 | #include "object.h" 5 | #include "technology.h" 6 | 7 | void postprocess_merge_shapes(struct object* object, struct technology_state* techstate); 8 | void postprocess_remove_layer_shapes_flat(struct object* object, const struct generics* layer); 9 | void postprocess_remove_layer_shapes(struct object* object, const struct generics* layer); 10 | 11 | #endif // OPC_POSTPROCESS_H 12 | -------------------------------------------------------------------------------- /src/scripts/list_anchors.lua: -------------------------------------------------------------------------------- 1 | local anchors = pcell.anchors(args.cell, cellargs) 2 | local sorted = {} 3 | for k, v in pairs(anchors) do 4 | table.insert(sorted, { name = k, info = v.info, conditions = v.conditions }) 5 | end 6 | table.sort(sorted, function(a, b) return a.name < b.name end) 7 | 8 | for _, entry in ipairs(sorted) do 9 | local doprint = true 10 | if args.anchornames then 11 | doprint = util.any_of(function(name) return string.match(entry.name, name) end, args.anchornames or {}) 12 | end 13 | if doprint then 14 | print(string.format("anchor: %s\n info: %s\n conditions: %s", entry.name, entry.info, entry.conditions or "none")) 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /src/scripts/list_parameters.lua: -------------------------------------------------------------------------------- 1 | -- FIXME: output cell parameters AFTER parameters have been processed in order to respect value changes in pfiles 2 | -- FIXME: is args.generictech currently used and supported? 3 | local params = pcell.parameters(args.cell, cellargs, args.generictech) 4 | local paramformat = args.parametersformat or "%n:\t\t%i" 5 | for _, P in ipairs(params) do 6 | local doprint = true 7 | if args.parameternames then 8 | doprint = util.any_of(function(name) return string.match(P.name, name) ~= nil end, args.parameternames) 9 | end 10 | local paramstr = string.gsub(paramformat, "%%%a", { 11 | ["%p"] = P.parent, 12 | ["%t"] = P.ptype, 13 | ["%n"] = P.name, 14 | ["%d"] = P.display or "_NONE_", 15 | ["%v"] = P.value, 16 | ["%a"] = P.argtype, 17 | ["%i"] = P.info or "", 18 | ["%r"] = tostring(P.readonly), 19 | ["%o"] = P.posvals and P.posvals.type or "everything", 20 | ["%s"] = (P.posvals and P.posvals.values) and table.concat(P.posvals.values, ";") or "" 21 | }) 22 | if doprint then 23 | print(paramstr) 24 | end 25 | end 26 | return 0 27 | -------------------------------------------------------------------------------- /src/skillexport.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_SKILLEXPORT_H 2 | #define OPC_SKILLEXPORT_H 3 | 4 | #include "export_common.h" 5 | 6 | struct export_functions* skillexport_get_export_functions(void); 7 | 8 | #endif // OPC_SKILLEXPORT_H 9 | -------------------------------------------------------------------------------- /src/tagged_value.c: -------------------------------------------------------------------------------- 1 | #include "tagged_value.h" 2 | 3 | #include 4 | #include 5 | 6 | #include "util.h" 7 | 8 | struct tagged_value { 9 | //void* value; 10 | union { 11 | int i; 12 | double d; 13 | char* str; 14 | }; 15 | enum tag { 16 | INTEGER, 17 | NUMBER, 18 | STRING, 19 | BOOLEAN 20 | } tag; 21 | }; 22 | 23 | struct tagged_value* _create(enum tag tag) 24 | { 25 | struct tagged_value* value = malloc(sizeof(*value)); 26 | value->tag = tag; 27 | return value; 28 | } 29 | 30 | struct tagged_value* tagged_value_create_integer(int i) 31 | { 32 | struct tagged_value* value = _create(INTEGER); 33 | value->i = i; 34 | return value; 35 | } 36 | 37 | struct tagged_value* tagged_value_create_number(double d) 38 | { 39 | struct tagged_value* value = _create(NUMBER); 40 | value->d = d; 41 | return value; 42 | } 43 | 44 | struct tagged_value* tagged_value_create_string(const char* str) 45 | { 46 | struct tagged_value* value = _create(STRING); 47 | value->str = util_strdup(str); 48 | return value; 49 | } 50 | 51 | struct tagged_value* tagged_value_create_boolean(int b) 52 | { 53 | struct tagged_value* value = _create(BOOLEAN); 54 | value->i = b; 55 | return value; 56 | } 57 | 58 | void tagged_value_destroy(void* vp) 59 | { 60 | struct tagged_value* v = vp; 61 | if(v->tag == STRING) 62 | { 63 | free(v->str); 64 | } 65 | free(vp); 66 | } 67 | 68 | int tagged_value_is_integer(const struct tagged_value* value) 69 | { 70 | return value->tag == INTEGER; 71 | } 72 | 73 | int tagged_value_is_number(const struct tagged_value* value) 74 | { 75 | return value->tag == NUMBER; 76 | } 77 | 78 | int tagged_value_is_string(const struct tagged_value* value) 79 | { 80 | return value->tag == STRING; 81 | } 82 | 83 | int tagged_value_is_boolean(const struct tagged_value* value) 84 | { 85 | return value->tag == BOOLEAN; 86 | } 87 | 88 | int tagged_value_get_integer(const struct tagged_value* value) 89 | { 90 | return value->i; 91 | } 92 | 93 | double tagged_value_get_number(const struct tagged_value* value) 94 | { 95 | return value->d; 96 | } 97 | 98 | const char* tagged_value_get_const_string(const struct tagged_value* value) 99 | { 100 | return value->str; 101 | } 102 | 103 | char* tagged_value_get_string(struct tagged_value* value) 104 | { 105 | return value->str; 106 | } 107 | 108 | int tagged_value_get_boolean(const struct tagged_value* value) 109 | { 110 | return value->i; 111 | } 112 | -------------------------------------------------------------------------------- /src/tagged_value.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_TAGGED_VALUE_H 2 | #define OPC_TAGGED_VALUE_H 3 | 4 | struct tagged_value; 5 | 6 | struct tagged_value* tagged_value_create_integer(int value); 7 | struct tagged_value* tagged_value_create_number(double value); 8 | struct tagged_value* tagged_value_create_string(const char* value); 9 | struct tagged_value* tagged_value_create_boolean(int value); 10 | void tagged_value_destroy(void*); 11 | 12 | int tagged_value_is_integer(const struct tagged_value* value); 13 | int tagged_value_is_number(const struct tagged_value* value); 14 | int tagged_value_is_string(const struct tagged_value* value); 15 | int tagged_value_is_boolean(const struct tagged_value* value); 16 | 17 | int tagged_value_get_integer(const struct tagged_value*); 18 | double tagged_value_get_number(const struct tagged_value*); 19 | const char* tagged_value_get_const_string(const struct tagged_value*); 20 | char* tagged_value_get_string(struct tagged_value*); 21 | int tagged_value_get_boolean(const struct tagged_value*); 22 | 23 | #endif /* OPC_TAGGED_VALUE_H */ 24 | -------------------------------------------------------------------------------- /src/terminal_colors.c: -------------------------------------------------------------------------------- 1 | #include "terminal_colors.h" 2 | 3 | #include 4 | 5 | void terminal_set_color_RGB(unsigned char R, unsigned char G, unsigned char B) 6 | { 7 | fprintf(stdout, "\033[38;2;%hhu;%hhu;%hhum", R, G, B); 8 | } 9 | 10 | void terminal_set_bold(void) 11 | { 12 | fputs("\033[1m", stdout); 13 | } 14 | 15 | void terminal_reset_color(void) 16 | { 17 | fputs(COLOR_NORMAL, stdout); 18 | } 19 | 20 | -------------------------------------------------------------------------------- /src/terminal_colors.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_TERMINAL_COLORS_H 2 | #define OPC_TERMINAL_COLORS_H 3 | 4 | /* 256 colors: 5 | * ESC[ 38;2;⟨r⟩;⟨g⟩;⟨b⟩ m Select RGB foreground color 6 | * ESC[ 48;2;⟨r⟩;⟨g⟩;⟨b⟩ m Select RGB background color 7 | */ 8 | 9 | #define COLOR_RGB(r, g, b) "\033[38;2;" #r ";" #g ";" #b "m" 10 | 11 | #define COLOR_BOLD "\033[1m" 12 | 13 | #define COLOR_BLACK "\033[0;30m" 14 | #define COLOR_BLACK_BOLD "\033[1;30m" 15 | #define COLOR_RED "\033[0;31m" 16 | #define COLOR_RED_BOLD "\033[1;31m" 17 | #define COLOR_GREEN "\033[0;32m" 18 | #define COLOR_GREEN_BOLD "\033[1;32m" 19 | #define COLOR_YELLOW "\033[0;33m" 20 | #define COLOR_YELLOW_BOLD "\033[1;33m" 21 | #define COLOR_BLUE "\033[0;34m" 22 | #define COLOR_BLUE_BOLD "\033[1;34m" 23 | #define COLOR_PURPLE "\033[0;35m" 24 | #define COLOR_PURPLE_BOLD "\033[1;35m" 25 | #define COLOR_CYAN "\033[0;36m" 26 | #define COLOR_CYAN_BOLD "\033[1;36m" 27 | #define COLOR_WHITE "\033[0;37m" 28 | #define COLOR_WHITE_BOLD "\033[1;37m" 29 | #define COLOR_NORMAL "\033[0m" 30 | 31 | void terminal_set_color_RGB(unsigned char R, unsigned char G, unsigned char B); 32 | void terminal_set_bold(void); 33 | void terminal_reset_color(void); 34 | 35 | #endif /* OPC_TERMINAL_COLORS_H */ 36 | -------------------------------------------------------------------------------- /src/transformationmatrix.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_TRANSFORMATIONMATRIX_H 2 | #define OPC_TRANSFORMATIONMATRIX_H 3 | 4 | #include "point.h" 5 | 6 | struct transformationmatrix; 7 | 8 | struct transformationmatrix* transformationmatrix_create(void); 9 | void transformationmatrix_destroy(struct transformationmatrix* matrix); 10 | void transformationmatrix_identity(struct transformationmatrix* matrix); 11 | void transformationmatrix_chain_inline(struct transformationmatrix* lhs, const struct transformationmatrix* rhs); 12 | struct transformationmatrix* transformationmatrix_chain(const struct transformationmatrix* lhs, const struct transformationmatrix* rhs); 13 | struct transformationmatrix* transformationmatrix_copy(const struct transformationmatrix* old); 14 | struct transformationmatrix* transformationmatrix_invert(const struct transformationmatrix* old); 15 | void transformationmatrix_move_to(struct transformationmatrix* matrix, coordinate_t x, coordinate_t y); 16 | void transformationmatrix_move_x_to(struct transformationmatrix* matrix, coordinate_t x); 17 | void transformationmatrix_move_y_to(struct transformationmatrix* matrix, coordinate_t y); 18 | void transformationmatrix_translate(struct transformationmatrix* matrix, coordinate_t dx, coordinate_t dy); 19 | void transformationmatrix_translate_x(struct transformationmatrix* matrix, coordinate_t dx); 20 | void transformationmatrix_translate_y(struct transformationmatrix* matrix, coordinate_t dy); 21 | void transformationmatrix_scale(struct transformationmatrix* matrix, double factor); 22 | void transformationmatrix_mirror_x(struct transformationmatrix* matrix); 23 | void transformationmatrix_mirror_y(struct transformationmatrix* matrix); 24 | void transformationmatrix_mirror_origin(struct transformationmatrix* matrix); 25 | void transformationmatrix_rotate_90_right(struct transformationmatrix* matrix); 26 | void transformationmatrix_rotate_90_left(struct transformationmatrix* matrix); 27 | void transformationmatrix_apply_transformation(const struct transformationmatrix* matrix, struct point* pt); 28 | void transformationmatrix_apply_transformation_rot_mirr(const struct transformationmatrix* matrix, struct point* pt); 29 | void transformationmatrix_apply_transformation_xy(const struct transformationmatrix* matrix, coordinate_t* x, coordinate_t* y); 30 | void transformationmatrix_apply_inverse_transformation(const struct transformationmatrix* matrix, struct point* pt); 31 | void transformationmatrix_apply_inverse_transformation_xy(const struct transformationmatrix* matrix, coordinate_t* x, coordinate_t* y); 32 | const coordinate_t* transformationmatrix_get_coefficients(const struct transformationmatrix* matrix); 33 | 34 | #endif /* OPC_TRANSFORMATIONMATRIX_H */ 35 | -------------------------------------------------------------------------------- /src/union.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_UNION_H 2 | #define OPC_UNION_H 3 | 4 | #include "point.h" 5 | #include "vector.h" 6 | 7 | int rectangle_union(coordinate_t blx1, coordinate_t bly1, coordinate_t trx1, coordinate_t try1, coordinate_t blx2, coordinate_t bly2, coordinate_t trx2, coordinate_t try2, coordinate_t* blx, coordinate_t* bly, coordinate_t* trx, coordinate_t* try); 8 | size_t union_rectangle_all(struct vector* rectangles); 9 | 10 | #endif // OPC_UNION_H 11 | -------------------------------------------------------------------------------- /src/util.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_UTIL_H 2 | #define OPC_UTIL_H 3 | 4 | unsigned int util_num_digits(unsigned int n); 5 | int util_match_string(const char* str, const char* match); 6 | int util_split_string(const char* src, char delim, char** first, char** second); 7 | void util_append_string(char* target, const char* str); 8 | int util_file_exists(const char* path); 9 | char* util_strdup(const char* str); 10 | char* util_concat_path(const char* prefix, const char* suffix); 11 | 12 | #define util_min(a, b) ((a) < (b) ? (a) : (b)) 13 | #define util_max(a, b) ((a) > (b) ? (a) : (b)) 14 | 15 | #endif // OPC_UTIL_H 16 | -------------------------------------------------------------------------------- /src/util_cmodule.c: -------------------------------------------------------------------------------- 1 | #include "util_cmodule.h" 2 | 3 | #include 4 | 5 | #include "lua/lauxlib.h" 6 | #include "lua/lualib.h" 7 | 8 | #include "lpoint.h" 9 | #include "union.h" 10 | 11 | int lrectangle_union(lua_State* L) 12 | { 13 | struct lpoint* bl1 = lpoint_checkpoint(L, 1); 14 | struct lpoint* tr1 = lpoint_checkpoint(L, 2); 15 | struct lpoint* bl2 = lpoint_checkpoint(L, 3); 16 | struct lpoint* tr2 = lpoint_checkpoint(L, 4); 17 | coordinate_t blx, bly, trx, try; 18 | int status = rectangle_union( 19 | point_getx(lpoint_get(bl1)), 20 | point_gety(lpoint_get(bl1)), 21 | point_getx(lpoint_get(tr1)), 22 | point_gety(lpoint_get(tr1)), 23 | point_getx(lpoint_get(bl2)), 24 | point_gety(lpoint_get(bl2)), 25 | point_getx(lpoint_get(tr2)), 26 | point_gety(lpoint_get(tr2)), 27 | &blx, &bly, &trx, &try 28 | ); 29 | if(!status) 30 | { 31 | lua_pushnil(L); 32 | } 33 | else 34 | { 35 | lua_newtable(L); 36 | lua_pushstring(L, "bl"); 37 | lpoint_create_internal_xy(L, blx, bly); 38 | lua_rawset(L, -3); 39 | lua_pushstring(L, "tr"); 40 | lpoint_create_internal_xy(L, trx, try); 41 | lua_rawset(L, -3); 42 | } 43 | return 1; 44 | } 45 | 46 | int open_lutil_cmodule_lib(lua_State* L) 47 | { 48 | lua_newtable(L); 49 | static const luaL_Reg modfuncs[] = 50 | { 51 | { "rectangle_union", lrectangle_union }, 52 | { NULL, NULL } 53 | }; 54 | luaL_setfuncs(L, modfuncs, 0); 55 | lua_setglobal(L, "util"); 56 | return 0; 57 | } 58 | 59 | -------------------------------------------------------------------------------- /src/util_cmodule.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_UTIL_CMODULE_H 2 | #define OPC_UTIL_CMODULE_H 3 | 4 | #include "lua/lua.h" 5 | 6 | int open_lutil_cmodule_lib(lua_State* L); 7 | 8 | #endif /* OPC_UTIL_CMODULE_H */ 9 | -------------------------------------------------------------------------------- /src/version.h: -------------------------------------------------------------------------------- 1 | #ifndef OPC_VERSION_H 2 | #define OPC_VERSION_H 3 | 4 | #define OPC_VERSION_MAJOR 0 5 | #define OPC_VERSION_MINOR 13 6 | #define OPC_VERSION_REVISION 0 7 | 8 | #endif /* OPC_VERSION_H */ 9 | -------------------------------------------------------------------------------- /tech/freePDK45/config.lua: -------------------------------------------------------------------------------- 1 | return { 2 | metals = 10 3 | } 4 | -------------------------------------------------------------------------------- /tech/freePDK45/constraints.lua: -------------------------------------------------------------------------------- 1 | return { 2 | ["Minimum Gate Extension"] = 60, 3 | ["Minimum Gate Length"] = 60, 4 | ["Minimum Gate Width"] = 200, 5 | ["Minimum Gate Space"] = 140, 6 | ["Minimum M1 Width"] = 80, 7 | ["Minimum M1 Space"] = 80, 8 | } 9 | -------------------------------------------------------------------------------- /tech/opc/config.lua: -------------------------------------------------------------------------------- 1 | return { 2 | metals = 10 3 | } 4 | -------------------------------------------------------------------------------- /tech/opc/constraints.lua: -------------------------------------------------------------------------------- 1 | return { 2 | ["Minimum Active Space"] = 200, 3 | ["Minimum Gate Extension"] = 100, 4 | ["Minimum Gate Length"] = 200, 5 | ["Minimum Gate Width"] = 500, 6 | ["Minimum Gate XSpace"] = 300, 7 | ["Minimum Gate YSpace"] = 300, 8 | ["Minimum M1 Width"] = 400, 9 | ["Minimum M1 Space"] = 400, 10 | } 11 | -------------------------------------------------------------------------------- /tech/skywater130/config.lua: -------------------------------------------------------------------------------- 1 | return { 2 | grid = 5, -- in nm 3 | metals = 6 4 | } 5 | -------------------------------------------------------------------------------- /tech/skywater130/constraints.lua: -------------------------------------------------------------------------------- 1 | return { 2 | ["Minimum Gate Extension"] = 120, 3 | ["Minimum Gate Length"] = 200, 4 | ["Minimum Gate Width"] = 1000, 5 | ["Minimum Gate Space"] = 400, 6 | ["Minimum M1 Width"] = 300, 7 | ["Minimum M1 Space"] = 300, 8 | } 9 | -------------------------------------------------------------------------------- /tech/skywater130/vias.lua: -------------------------------------------------------------------------------- 1 | return { 2 | contactgate = { 3 | entries = { 4 | { width = 170, height = 170, xspace = 250, yspace = 170, xenclosure = 40, yenclosure = 80 }, 5 | }, 6 | fallback = { width = 170, height = 170 }, 7 | }, 8 | contactsourcedrain = { 9 | entries = { 10 | { width = 170, height = 170, xspace = 170, yspace = 170, xenclosure = 40, yenclosure = 40 }, 11 | }, 12 | fallback = { width = 170, height = 170 }, 13 | }, 14 | viaM1M2 = { 15 | entries = { 16 | { width = 170, height = 170, xspace = 250, yspace = 170, xenclosure = 40, yenclosure = 80 }, 17 | }, 18 | fallback = { width = 170, height = 170 }, 19 | }, 20 | viaM2M3 = { 21 | entries = { 22 | { width = 150, height = 150, xspace = 170, yspace = 170, xenclosure = 55, yenclosure = 55 }, 23 | }, 24 | fallback = { width = 150, height = 150 }, 25 | }, 26 | viaM3M4 = { 27 | entries = { 28 | { width = 200, height = 200, xspace = 200, yspace = 200, xenclosure = 40, yenclosure = 40 }, 29 | }, 30 | fallback = { width = 200, height = 200 }, 31 | }, 32 | viaM4M5 = { 33 | entries = { 34 | { width = 200, height = 200, xspace = 200, yspace = 200, xenclosure = 60, yenclosure = 60 }, 35 | }, 36 | fallback = { width = 200, height = 200 }, 37 | }, 38 | viaM5M6 = { 39 | entries = { 40 | { width = 800, height = 800, xspace = 800, yspace = 800, xenclosure = 190, yenclosure = 190 }, 41 | }, 42 | fallback = { width = 800, height = 800 }, 43 | }, 44 | } 45 | -------------------------------------------------------------------------------- /tech/template/config.lua: -------------------------------------------------------------------------------- 1 | return { 2 | grid = 0.005 3 | } 4 | --------------------------------------------------------------------------------