Hi all! I just tried a simple design example with ...
# openlane
a
Hi all! I just tried a simple design example with 1 sram instance. For some reason the synthesis fails because it cannot identify the sky130_sram_1kbyte_1rw1r_8x1024_8 macro.
Copy code
4.1. Analyzing design hierarchy..
ERROR: Module `\sky130_sram_1kbyte_1rw1r_8x1024_8' referenced in module `\user_proj_example' in cell `\sram' is not part of the design.
[ERROR]: during executing: "yosys -c /openlane/scripts/yosys/synth.tcl -l /home/aanujdu/caravel_tut/caravel_example/openlane/user_proj_example/runs/user_proj_example/logs/synthesis/1-synthesis.log |& tee >&@stdout"
[ERROR]: Exit code: 1
[ERROR]: Last 10 lines:
child process exited abnormally
I also got a warning about the MGMT_AREA_ROOT variable. Makefile41 warning: undefined variable 'MGMT_AREA_ROOT' I am unsure of what to set it to. Can someone please help me with the above issues?
m
@Anuj Dubey No actual experience myself, but the
caravel_user_example
uses
mgmt_core_wrapper
which includes an sram module. Maybe take a look at that
config.tcl
. If you haven't already, in
caravel_user_example
,
make install_mcw
.
r
I'm also working on integrating an SRAM macro into a design, which is a process with a lot of steps, as it seems. Here are some starting points based on my experiences. (a) you have to decide whether (1) to integrate your own block plus the SRAM blocks inside the user project wrapper, to (2) have a monolotic user_project_wrapper with everything integrated, or (3) integrate the SRAM blocks into the user_project, which then goes into wrapper. I'm currently very unsure which approach makes most sense as I'm running into different problems in (1) and (2), and haven't tried (3) yet. In any case, in the part in which the SRAM cells are integrated, you need to add the verilog files or the SRAM block as a blackbox and the LEF and GDS files of the SRAM block by hand, such as by adding the following to config.tcl: set ::env(VERILOG_FILES_BLACKBOX) "\ $::env(PDK_ROOT)/sky130A/libs.ref/sky130_sram_macros/verilog/sky130_sram_2kbyte_1rw1r_32x512_8.v \ $::env(PDK_ROOT)/sky130A/libs.ref/sky130_sram_macros/verilog/sky130_sram_1kbyte_1rw1r_32x256_8.v" set ::env(EXTRA_LEFS) "\ $::env(PDK_ROOT)/sky130A/libs.ref/sky130_sram_macros/lef/sky130_sram_2kbyte_1rw1r_32x512_8.lef \ $::env(PDK_ROOT)/sky130A/libs.ref/sky130_sram_macros/lef/sky130_sram_1kbyte_1rw1r_32x256_8.lef" set ::env(EXTRA_GDS_FILES) "\ $::env(PDK_ROOT)/sky130A/libs.ref/sky130_sram_macros/gds/sky130_sram_2kbyte_1rw1r_32x512_8.gds \ $::env(PDK_ROOT)/sky130A/libs.ref/sky130_sram_macros/gds/sky130_sram_1kbyte_1rw1r_32x256_8.gds" This gets rid of your first problem, I hope. Note that if you integrate the SRAM blocks in the wrapper, the entries above will be longer. Then, you need to place the SRAM cells by hand as the auto-placer will not do, as it looks - detailed placement will fail if you try this. To do this, you need to know the naming path of the macros, which I didn't find documented anywhere. In your case, it may simply be "sram". Follow the syntax of the existing "macros.cfg" files and reference it in your config.tcl as well.
m
at the moment because of power supply limitations, you should put the sram block at the top level.
a
Hi Ruediger, thanks for the detailed explanation and pointers. However, since I am new to the whole flow, esp. with macros, I am unclear on some points. For example, I am not able to understand how the three approaches differ exactly, or what is meant by "integration" here. Like what changes in terms of the files and steps that I need to modify/create and execute if take the three approaches for a simple design, like let's say an SRAM macro and a processor core instantiated within the user_project_wrapper module. I apologize if this question is too basic. Meanwhile, I'll try setting the variables in the config.tcl of user_project_wrapper to see if the issue is resolved.
r
I'm also still trying to figure out how everything fits together, especially since the documentation is a bit scattered. In the example Caravel user project, there is a "user_project_wrapper" and a "user_project". The former has a fixed size and a fixed interface, so that it fits exactly on the Caravel SoC. The example project is built such that the actual logic is in the user_project, and you can compile that to a "macro", which is a pre-compiled chip part. Compiling the "user_project_wrapper" then means placing the macro into the area of fixed size and compiling the connections. There is the possibility to skip having a "user_project" altogether and compile directly to a "user project wrapper". This is possibility (2). This is mentioned in some documentation somewhere, which I can't find right now. The alternative is to leave the project structure as it is, with first compiling the user_project macro, followed by compiling the user_project_wrapper macro. While you can design hierarchically in Verilog, the SRAM block can't be part of the "user_ project", as it seems (the power supply limits mentioned by Matt Venn above). This normally means that in the user_project_wrapper.v Verlilog file, you instantiate the SRAM, add some wires for connecting the SRAM, and add these as input/output to your "user_project" module in the Verilog file. The compilation process to silicon for both the user project and the wrapper are controlled by the openlane/<targetname>/config.tcl files. This is where, for the user_project_wrapper, you need to add references to LEF, GDS, and Verilog files for the SRAM macros that you use (see above). Afterwards, you double-check that the following line already exists in the config.tcl: set ::env(MACRO_PLACEMENT_CFG) $script_dir/macro.cfg Then, edit this "macro.cfg" file, which contains lines that define where exactly the big macros are placed. Every line consists of the name of the macro (separating items with dots when nesting modules), the X position (in micrometers?), the Y position, and the orientation (e.g., "N" for "North"). I don't have a clue how to come up with good positions for the macros. Try starting with 100 100 if it's a single SRAM block that you are placing. Bad macro positions can cause problems with power generation and routing, though, with error messages that don't appear to be connected to macro placement.
a
Wow! That's the best description of the entire flow that I have read until now. Really appreciate you taking out time and writing this out to guide me with the future steps. Now that I understand the three approaches, I know that I am trying out the first approach of instantiating the SRAM within user_project, which is not preferable based on Matt's comments. But let's say I go ahead with that for the moment. Will the flow successfully generate the gds? I got stuck at the DRC step I believe, with the following error.
Copy code
###############################################################################
# Design Rules
###############################################################################
set_max_fanout 5.0000 [current_design]
[INFO]: Setting RC values...
[INFO RSZ-0027] Inserted 34 input buffers.
[INFO RSZ-0028] Inserted 69 output buffers.
[INFO RSZ-0058] Using max wire length 2319um.
[INFO RSZ-0039] Resized 152 instances.
[INFO RSZ-0042] Inserted 173 tie sky130_fd_sc_hd__conb_1 instances.
[INFO DPL-0034] Detailed placement failed on:
[INFO DPL-0035]  sram
[ERROR DPL-0036] Detailed placement failed.
Error: resizer.tcl, 78 DPL-0036
[ERROR]: during executing openroad script /openlane/scripts/openroad/resizer.tcl
[ERROR]: Exit code: 1
[ERROR]: Last 10 lines:
child process exited abnormally
I am not sure what is DPL 0036 exactly, or if there is documentation on a possible fix. Have you faced this error? Is it because of not creating a macro.cfg in the user_project's config.tcl? I didn't because I wasn't sure if I need it in the first approach--it doesn't exist in the caravel/user_proj_example directory by default (unlike the caravel/user_project_wrapper directory) and config.tcl file also didn't contain the set command (again unlike the tcl file of the wrapper module).
r
@Anuj Dubey , I think that once upon a time I also tried having the SRAM placed automatically, but that also didn't work out. Somewhere I read that during global routing, the size of the cells to be placed is not used, so that not enough space is reserved for the SRAM, and hence it cannot be placed. I think that manually placing the SRAM blocks is a necessity as of now.
a
Okay, I'll try the manual placement and see if the issue is fixed. Thanks!
m
Anuj, check my current submission
I'm using sram and manually placing
I might not have added everything to the repo, but all the config is there
this is passing precheck and the tapeout failure is due to an iocell issue that is being fixed separately
a
Thanks a lot Matt! I'll check it out. 🙂
r
@Matt Venn Thanks for the Pointer! When building the user_project_wrapper of your zero_to_asic_mpw5 project with the latest version on GIT, there are no DRC violations, but the SRAM seems to be "empty". When changing the git commit for "openram_z2a" in "projects.yaml" in your "multi_project_tools" to the last version that contains the actual SRAM, the project wrapper buils well, but precheck fails with KLayout FEOL violations. May I ask how you fixed this? According to the comments in "projects.yaml", you came across this problem. I'm having the same problem with my project right now (using both 2kb and 1kb SRAMs with 32 bit word widths)
m
make sure you update the precheck. it passes on the efabless website
r
@Matt Venn Thanks a lot! That works. The "precheck" target of https://github.com/efabless/caravel_user_project/blob/main/Makefile seems to currently check out tag mpw-5a as the precheck version. Perhaps it makes sense to update this to a later version. I can add a pull request for https://github.com/efabless/caravel_user_project/blob/main/Makefile to reference the currently latest version of "mpw_check" if you want.
m
yes please
can confirm latest commit in mpw precheck is a05919fa2018c550852e405d98aa3fa37b2576be
and it should be b30e779ab0ff90e37e5c56795066a30804816e13
a
Quick question, @Matt Venn, since I can't see the verilog files in the repo: do you delete the body of the openram_z2a/src/sky130_sram_1kbyte_1rw1r_32x256_8.v file after copying it from the pdks directory, and do you add the (* blackbox *) attribute to it? Essentially, how do you ensure that the sram's verilog does not get synthesized?
m
Now precheck works with the full version
I add all the top level verilog to the blackbox list in config.tcl
a
Thanks for that info Matt. I tried to configure similar to the openram repo you have pointed to. However, for some reason, the tool synthesizes the user_proj_example module instead of user_project_wrapper even though I am running make user_project_wrapper. Do I need to configure something for the tool to understand that there is no user_proj_example module in my project and I am directly trying to compile the user_project_wrapper module?
m
The makefile is broken
Check this commit
a
I see. Let me try.
Okay that worked. However, I am facing errors in LVS. Could you please help me on how to go about fixing these errors and where can I find the LVS log?
Copy code
Creating placeholder cell definition for module sky130_sram_1kbyte_1rw1r_32x256_8.
Reading setup file /home/aanujdu/caravel_tut/pdks/sky130A/libs.tech/netgen/sky130A_setup.tcl
Comparison output logged to file /home/aanujdu/caravel_tut/caravel_example/openlane/user_project_wrapper/runs/user_project_wrapper/logs/finishing/29-user_project_wrapper.lef.log
Logging to file "/home/aanujdu/caravel_tut/caravel_example/openlane/user_project_wrapper/runs/user_project_wrapper/logs/finishing/29-user_project_wrapper.lef.log" enabled
Circuit sky130_sram_1kbyte_1rw1r_32x256_8 contains no devices.

Contents of circuit 1:  Circuit: 'user_project_wrapper'
Circuit user_project_wrapper contains 1 device instances.
  Class: sky130_sram_1kbyte_1rw1r_32x256_8 instances:   1
Circuit contains 122 nets, and 525 disconnected pins.
Contents of circuit 2:  Circuit: 'user_project_wrapper'
Circuit user_project_wrapper contains 1 device instances.
  Class: sky130_sram_1kbyte_1rw1r_32x256_8 instances:   1
Circuit contains 121 nets, and 525 disconnected pins.

Circuit 1 contains 1 devices, Circuit 2 contains 1 devices.
Circuit 1 contains 122 nets,    Circuit 2 contains 121 nets. *** MISMATCH ***

Result: Netlists do not match.
Logging to file "/home/aanujdu/caravel_tut/caravel_example/openlane/user_project_wrapper/runs/user_project_wrapper/logs/finishing/29-user_project_wrapper.lef.log" disabled
LVS Done.
LVS reports:
    net count difference = 1
    device count difference = 0
    unmatched nets = 1
    unmatched devices = 0
    unmatched pins = 0
    property failures = 0

Total errors = 2
[ERROR]: There are LVS errors in the design according to Netgen LVS.
[INFO]: Calculating Runtime From the Start...
[INFO]: Generating Final Summary Report...
[INFO]: Design Name: user_project_wrapper
Run Directory: /home/aanujdu/caravel_tut/caravel_example/openlane/user_project_wrapper/runs/user_project_wrapper
Source not found.
----------------------------------------

LVS Summary:
Source: /home/aanujdu/caravel_tut/caravel_example/openlane/user_project_wrapper/runs/user_project_wrapper/logs/finishing/29-user_project_wrapper.lvs.lef.log
    net count difference = 1
    unmatched nets = 1
Total errors = 2
----------------------------------------

Antenna Summary:
No antenna report found.
[INFO]: check full report here: /home/aanujdu/caravel_tut/caravel_example/openlane/user_project_wrapper/runs/user_project_wrapper/reports/final_summary_report.csv
[INFO]: Saving runtime environment...
[ERROR]: Flow failed.
[INFO]: The failure may have been because of the following warnings:
[WARNING]: Skipping Tap/Decap Insertion.
[WARNING]: All internal macros will not be connected to power.
[WARNING]: All internal macros will not be connected to power.
[WARNING]: All internal macros will not be connected to power.


    while executing
"flow_fail"
    (procedure "quit_on_lvs_error" line 11)
    invoked from within
"quit_on_lvs_error -log $count_lvs_log"
    (procedure "run_lvs" line 80)
    invoked from within
"run_lvs"
    (procedure "run_lvs_step" line 11)
    invoked from within
"[lindex $step_exe 0] [lindex $step_exe 1] "
    (procedure "run_non_interactive_mode" line 55)
    invoked from within
"run_non_interactive_mode {*}$argv"
    invoked from within
"if { [info exists flags_map(-interactive)] || [info exists flags_map(-it)] } {
        puts_info "Running interactively"
        puts_info "Note, that post_run_hook..."
    (file "/openlane/flow.tcl" line 412)
Makefile:41: recipe for target 'user_project_wrapper' failed
make[1]: *** [user_project_wrapper] Error 1
make[1]: Leaving directory '/home/aanujdu/caravel_tut/caravel_example/openlane'
Makefile:69: recipe for target 'user_project_wrapper' failed
make: *** [user_project_wrapper] Error 2
m
Cant check now but first thing id check is if there are routing errors that are causing lvs
I had to add obstruction layers on openram to get error free routing
a
Okay. That actually reminds me of another question that I had regarding your openram repo. What is/are the use/contents of obstruction.tcl file that you have added in the config.tcl. I could not find either the obstruction.tcl file or info.yaml file.
m
I might not have committed it... Sorry
My z2a openram repo info.yaml specifies the obstruction layers
a
Got it. Let me check that out then.
m
@Anuj Dubey Check
/home/aanujdu/caravel_tut/caravel_example/openlane/user_project_wrapper/runs/user_project_wrapper/logs/finishing/29-user_project_wrapper.lef.log
for the net differences. If the problem is not obvious, you can post the last portion of the log that shows the errors here.
r
@Anuj Dubey The following is not exactly a solution, but perhaps helpful anyway. I'm currently adjusting the positions of the macros in my user_project_wrapper to reduce "slow" slew rates. For some position combinations of the macros, I'm also seeing that the resulting hardened user_project_wrapper fails LVS. Not sure what exactly the problem is, but it only happens for few macro position combinations. With slightly different macro positions, the detailed router then produces something entirely different and the problem vanishes. I've also had cases where later I got warnings such as _Ports "vssa1_uq0" and "vssd2_uq0" are electrically shorted_). Again, that only happens for some macro positions in the wrapper. What I found helpful was to start with placing macros with lots of space in between, and then to successively move them closer, watching for errors and warnings that pop up when placing them too close. Note that playing around with macro positions until things happen to work is not an actual solution, but may still be useful.
a
@Mitch Bailey: I took a look at the log you pointed to. Since I am completely new to physical design, I am not really sure how to decipher it. What are these two circuits that the log is referring to in the attached snippet? I have simply instantiated an sram inside user_project_wrapper as follows. Could it be because of the zero tie-offs of the csb inputs? I did that to always enable the ram ports.
Copy code
sky130_sram_1kbyte_1rw1r_32x256_8 openram_1kB
    (
    `ifdef USE_POWER_PINS
        .vccd1 (vccd1),
        .vssd1 (vssd1),
    `endif

        .clk0 (user_clock2),
        .csb0 (1'b0),
        .web0 (wbs_we_i),
        .wmask0 (wbs_sel_i),
        .addr0 (wbs_adr_i[7:0]),
        .din0 (wbs_dat_i),
        .dout0 (la_data_out[31:0]),

        .clk1 (user_clock2),
        .csb1 (1'b0),
        .addr1 (wbs_adr_i[15:8]),
        .dout1 (la_data_out[63:32])
    );
@Ruediger Ehlers: thanks for sharing your experience. Based on Matt's repo, I tried
openram_1kB 344 475.5 N
for starters. Maybe I'll retry with (100, 100) as you had mentioned previously.
m
Looks like the csb ports may be unconnected. Can you check on the gds?
a
Which gds file are you referring to? I see the following files in results/finishing directory. user_project_wrapper.gds user_project_wrapper.klayout.gds user_project_wrapper.magic.gds Also, how do I open this file and check for an unconnected port?
m
Not sure which file is best. Maybe try
user_project_wrapper.gds
first? Do you have klayout? 1. Open the gds 2. set the top cell to
sky130_sram_1kbyte_1rw1r_32x256_8
3. search for
csb*
text 4. remember the location 5. set the top cell to
user_project_wrapper
6. check the
csb*
locations from the previous step
a
Just installed klayout and opened the GDS. I can see csb1 in the top cell view of sram (image attached). However, I can't visually find the other labels very clearly either in the sram as top or the user_project_wrapper as top. Is there a search option in klayout?
m
do you have any routing errors? they should be reported in runs/user_project_wrapper/errors.log
a
I see the following content in errors.log.
Copy code
[ERROR]: There are LVS errors in the design according to Netgen LVS.
[ERROR]: Flow failed.
I am using the same config.tcl as your openram repo except the obstruction.tcl file.
m
csb0 is bottom left
image.png
m
There is a search function. Pretty powerful. Edit->Search and Replace
a
Thanks for the locations, @Matt Venn. I am not sure why would the csb nets stay unconnected in the layout. Thanks @Mitch Bailey, let me check this in the two views.
m
can you show your gds? This is why I'm asking about routing errors.
a
There you go!
m
that is not helpful 😆 either zoom in or share the gds with a link to your repo
a
Haha! I took the "show" word too literally! Sorry about that. I am completely new to physical design. I have attached the gds file.
🙌 1
m
just so you know, best practice is to keep your repo up-to-date on github and then you can just share the link
also we have limited room the free slack, so big files mean the chat disappears faster
and your verilog?
user_project_wrapper.v ?
a
I tried pushing it to the repo first but these files are put as gitignores I believe. I didn't want to fiddle with the git config since some of the make commands also use git and thus kept it unchanged.
Copy code
module user_project_wrapper #(
    parameter BITS = 32
) (
`ifdef USE_POWER_PINS
    inout vdda1,	// User area 1 3.3V supply
    inout vdda2,	// User area 2 3.3V supply
    inout vssa1,	// User area 1 analog ground
    inout vssa2,	// User area 2 analog ground
    inout vccd1,	// User area 1 1.8V supply
    inout vccd2,	// User area 2 1.8v supply
    inout vssd1,	// User area 1 digital ground
    inout vssd2,	// User area 2 digital ground
`endif

    // Wishbone Slave ports (WB MI A)
    input wb_clk_i,
    input wb_rst_i,
    input wbs_stb_i,
    input wbs_cyc_i,
    input wbs_we_i,
    input [3:0] wbs_sel_i,
    input [31:0] wbs_dat_i,
    input [31:0] wbs_adr_i,
    output wbs_ack_o,
    output [31:0] wbs_dat_o,

    // Logic Analyzer Signals
    input  [127:0] la_data_in,
    output [127:0] la_data_out,
    input  [127:0] la_oenb,

    // IOs
    input  [`MPRJ_IO_PADS-1:0] io_in,
    output [`MPRJ_IO_PADS-1:0] io_out,
    output [`MPRJ_IO_PADS-1:0] io_oeb,

    // Analog (direct connection to GPIO pad---use with caution)
    // Note that analog I/O is not available on the 7 lowest-numbered
    // GPIO pads, and so the analog_io indexing is offset from the
    // GPIO indexing by 7 (also upper 2 GPIOs do not have analog_io).
    inout [`MPRJ_IO_PADS-10:0] analog_io,

    // Independent clock (on independent integer divider)
    input   user_clock2,

    // User maskable interrupt signals
    output [2:0] user_irq
);
    sky130_sram_1kbyte_1rw1r_32x256_8 openram_1kB
    (
    `ifdef USE_POWER_PINS
        .vccd1 (vccd1),
        .vssd1 (vssd1),
    `endif

        .clk0 (user_clock2),
        .csb0 (1'b0),
        .web0 (wbs_we_i),
        .wmask0 (wbs_sel_i),
        .addr0 (wbs_adr_i[7:0]),
        .din0 (wbs_dat_i),
        .dout0 (la_data_out[31:0]),

        .clk1 (user_clock2),
        .csb1 (1'b0),
        .addr1 (wbs_adr_i[15:8]),
        .dout1 (la_data_out[63:32])
    );

/*--------------------------------------*/
/* User project is instantiated  here   */
/*--------------------------------------*/

endmodule	// user_project_wrapper

`default_nettype wire
m
ahah
ok I think I know what it is
in the top level, you can't use anything that will get synthesised to anything other than a wire
so those 1'b0 will get dropped
it should cause an error
I would connect them to the logic analyser and then in the firmware set them low.
that's the easiest option probably
a
Ahh I see. So no 0 or 1 tie-offs in the top module I guess. Cool, I'll make these changes and try to rerun the flow. Btw uploaded the config and verilog at https://github.com/aanujdu/caravel_tut/tree/trial1 🙂
Copy code
user_project_wrapper
----------------------------------------
Metal3 > 3um spacing to unrelated m3 < 0.4um (met3.3d)
----------------------------------------
 823.470um 557.860um 823.560um 558.260um
 823.470um 556.050um 823.560um 558.260um
 823.470um 556.040um 823.560um 556.050um
 823.470um 555.760um 823.560um 556.040um
 823.470um 555.750um 823.560um 555.760um
 823.470um 549.700um 823.560um 550.100um
 823.470um 547.890um 823.560um 550.100um
 823.470um 547.880um 823.560um 547.890um
 823.470um 547.600um 823.560um 547.880um
 823.470um 547.590um 823.560um 547.600um
 823.470um 542.900um 823.560um 543.300um
 823.470um 541.090um 823.560um 543.300um
 823.470um 541.080um 823.560um 541.090um
 823.470um 540.800um 823.560um 541.080um
 823.470um 540.790um 823.560um 540.800um
 823.470um 857.060um 823.560um 857.460um
 823.470um 856.625um 823.560um 857.460um
 823.465um 856.600um 823.560um 856.625um
 823.465um 856.320um 823.490um 856.600um
 823.490um 856.320um 823.560um 856.600um
 823.465um 856.295um 823.560um 856.320um
----------------------------------------
[INFO]: COUNT: 21
[INFO]: Should be divided by 3 or 4
I am getting these drc errors once I connect the csb lines to the lsb bits of la_data_in.
m
but no lvs?
a
Umm, don't think so, because the errors.log only mentions the 21 DRC violations.
Copy code
[ERROR]: There are violations in the design after Magic DRC.
[ERROR]: Total Number of violations is 21
[ERROR]: Flow failed.
m
great! progress!
so for DRC, you should load the drc .xml marker with klayout along with the gds and look at where the problems are
it's likely to do with the position of the macro, or the obstructions aren't set correctly]
a
Yup, progress indeed! I see. Could you please point me to some resource explaining how to address drc errors?
m
not sure there is such a thing
good question tho
have you pushed everything to your repo?
maybe we can use it as a demo to show how to find and resolve drc errors
a
I haven't yet. In addition to verilog and config, what else should I push? The runs directory?Such a video will be very helpful. I just tried to load the markers in klayout, but I have no clue what they mean and how to go about fixing those.
m
if you do a git status then you can see everything that has changed
so all of that
then any extra RTL that you have added, and any extra GDS/LEF of any macros
a
Got it
m
I'm finishing for the day, try to get it all up online and I can take a look tomorrow
a
I've pushed everything to the repo. Looking forward to your feedback.
m
here's a quick and dirty demo to show how you can load xml markers with klayout to find where drc issue are:

https://youtu.be/ieE24mvkLi4

🙌 2
so in this case it's because the wiggles in the routing are happening too close to the openram macro, which is why you have to use obstructions
use this obs config:
Copy code
set ::env(GLB_RT_OBS)  "li1  0    0   2920    3520,
       met1 344.0 475.5 823.78 873.0,
       met2 344.0 475.5 823.78 873.0,
       met3 344.0 475.5 823.78 873.0,
       met4 344.0 475.5 823.78 873.0"
and uncomment the line in the config.tcl to read it
then you will get no drc
a
I see. Thanks for looking into it and providing a fix Matt. I'll give this a shot in a while. How did you figure out the issue? Is the exact error mentioned somewhere, or you just knew it after visually inspecting the markers on gds? Can you also please elaborate on the error a bit more if possible? Like what is the exact rule and how is it violated in the current layout—I'm not sure if I understand what you mean by wiggles in routing? Finally, what do these obstructions obstruct exactly and how would it fix that violation. Sorry for asking too many questions.
m
i was quick to find it because I'd already hit it myself
I don't actually understand why the unrelated met3 drc got hit, as there isn't any unrelated met3 about. but it's basically caused by the routing happening inside the footprint of the macro. so the obstruction forces that to happen outside