Hi Tim. We are trying to debug an issue where writ...
# magic
h
Hi Tim. We are trying to debug an issue where writing the LEF file for the full Tiny Tapeout chip takes a lot of time, over an hour. We use the openlane2 flow to combine the designs, and the particular step runs a magic tcl script along the lines of:
Copy code
drc off
gds read gds/openframe_project_wrapper.gds
lef nocheck vccd1 vssd1
lef write lef/openframe_project_wrapper.lef -hide
quit
We don't actually start from the gds but from a bunch of smaller pieces, but it's easier to reproduce this way. You can find the gds in https://github.com/TinyTapeout/tinytapeout-06/releases/download/tapeout-ci2404/efabless_submission.zip The issue was discovered with magic 8.3.466 but it's still present on 8.3.479. I've run it through a profiler and will attach its output in a reply. Have you got an idea to make it faster? By the way, is the top-level LEF file necessary to complete the flow and make a chipignite submission or could we just skip it entirely?
These are the hot code paths:
Copy code
-   93,80%     0,00%  magicdnull  /usr/lib64/libtcl8.6.so                                                                                                          
     TclInvokeStringCommand
     _tcl_dispatch
     TxTclDispatch
   - WindSendCommand
      - 93,80% DBWcommands
         - WindExecute
            - 67,87% CmdCalma
               - CalmaReadFile
                  - 55,57% CIFReadCellCleanup
                     - 55,45% DRCCheckThis
                        - 55,11% DRCCheckThis
                           - 41,47% DRCCheckThis
                                0,89% DRCCheckThis
                  - 12,30% calmaParseStructure
                     - 9,34% CIFPaintCurrent
                        - 6,08% CIFGenLayer
                           - 3,75% cifSrTiles
                              - 3,24% DBSrPaintArea
                                 - 2,34% cifPaintFunc
                                    - 2,08% DBNMPaintPlane0.localalias
                                       - 2,02% DBPaintPlane0
                                          - 0,87% TiAlloc
                                               getTileFromTileStore
                           - 1,82% DBSrPaintArea
                              - 1,06% cifPaintFunc
                                 - 0,97% DBNMPaintPlane0.localalias
                                      0,96% DBPaintPlane0
                        - 2,80% DBSrPaintArea
                           - 2,44% cifPaintCurrentFunc
                              - 2,38% DBNMPaintPlane0.localalias
                                   2,36% DBPaintPlane0
                     - 2,12% calmaParseElement
                        - 0,98% calmaElementSref
                           - 0,89% DBSrPaintArea
                              - 0,73% gdsCopyPaintFunc
                                 - 0,69% DBNMPaintPlane0.localalias
                                      0,68% DBPaintPlane0
                          0,68% calmaElementBoundary
            - 25,91% CmdLef
                 LefWriteCell
               - lefWriteMacro
                  - 24,09% DBCellCopyAllPaint
                       DBTreeSrTiles
                     - dbCellPlaneSrFunc
                        - 24,08% DBCellSrArea
                             DBSrCellPlaneArea
                             dbCellSrFunc
                           - dbCellPlaneSrFunc
                              - 22,15% DBCellSrArea
                                 - 22,15% DBSrCellPlaneArea
                                    - 22,14% dbCellSrFunc
                                       - 22,13% dbCellPlaneSrFunc
                                          - 21,83% DBSrPaintArea
                                             - 20,84% dbCopyAllPaint
                                                - 20,35% DBPaintPlaneWrapper
                                                   - 11,44% DBNMPaintPlane0.localalias
                                                      - 11,36% DBPaintPlane0
                                                           0,51% TiJoinY
                                                     8,85% DBMergeNMTiles0
                              - 1,93% DBSrPaintArea
                                 - 1,78% dbCopyAllPaint
                                    - 1,68% DBPaintPlaneWrapper
                                       - 1,34% DBNMPaintPlane0.localalias
                                            1,32% DBPaintPlane0
                  - 0,81% DBCellClearDef
                     - DBClearPaintPlane
                          0,81% DBFreePaintPlane
                    0,52% DBSrPaintArea
t
I have no idea what the project top-level LEF file is used for. It is not part of my script that assembles the full chip.
๐Ÿ‘ 1
The problem with the long run time is that magic is checking all nets for antenna gate and diffusion areas. The
lef nocheck
avoids the worst of the problem from power supplies (although as long as the power supplies are annotated as such, the
lef nocheck vccd1 vssd1
line should not be necessary). If the cell is large enough, then this process will take a very long time. Potentially you can do
lef nocheck
followed by all of the pin names (which is going to be a very long list; if it seems like this is something that needs to be done often, I can add code to handle
lef nocheck all
or
lef notheck *
or something). Although the user project area is a subcell of the caravel SoC core, since the caravel SoC core is built around an empy user project, there is no way that the antenna information from the LEF file for a specific user project can be used; I don't see any need to create the LEF file.
๐Ÿ‘ 1
h
Thank you.
We have removed the LEF and it's passing tapeout. Out of curiosity I also tried the quick patch below to support
lef nocheck *
and it gives a ~40% speedup, so I think it makes sense to implement something similar (even though we won't use it on TT now).
Copy code
--- lef/lefWrite.c
+++ lef/lefWrite.c
@@ -1468,7 +1468,8 @@
            // Check for net names to ignore for antenna checks.
            if (!ignored)
                for (lnn = lefIgnoreNets; lnn; lnn = lnn->lnn_next)
-                   if (!strcmp(lnn->lnn_name, lab->lab_text))
+                   if (!strcmp(lnn->lnn_name, lab->lab_text) ||
+                       !strcmp(lnn->lnn_name, "*"))
                        ignored = TRUE;
 
            if (!ignored || (setback != 0))
t
Thanks for the code; I'll make the update.
๐Ÿ‘ 2