limbo018/DREAMPlace

About using OpenTimer get timing

Opened this issue · 4 comments

Hi Professor Lin, I'm reading and trying the LR-based detailed placement from your paper dreamplace 4.0, and I'm trying to use OpenTimer (from github) to get the timing information. When using OpenTimer to analyze the simple benchmark in the iccad2015 file, there is a big difference between the results with using UI-timer in the official evaluate. When using the same .v, .lib, .sdc, and .spef files, among them sdc modifies set_input_transition like the benchmarks in dreamplace4.0, spef is generated using build_steiner() and write_incremental_spef() in evaluate, and is read as follows:

timer.read_celllib("simple/simple_Early.lib", ot::MIN);
timer.read_celllib("simple/simple_Late.lib", ot::MAX);
timer.read_verilog("simple/simple.v");
timer.read_sdc("simple/simple.sdc");
timer.read_spef("simple.spef");
timer.update_timing();

When using report_wns(), there is a big difference in the results of UI-timer and OpenTimer. At the same time, using report_at() and dump_at() to get arrival time respectively, the following results are obtained:
微信图片_20240414132737
微信图片_20240414132924
the results are from OpenTimer and UI-timer respectively. I guess there may be some problems with my method of using API. How should I adjust the API calls and whether I missed calling some APIs. Thank you very much!

You hit an interesting point. The two timers are indeed somehow different internally. OpenTimer should be newer, faster and more stable in general as it's written in modern c++ with cpp-taskflow enabled, built upon its predecessor UI-timer. Based on our experiences, OpenTimer calculates TNS by summing up all early, late, rise, fall values, which can be found here, while the official evaluator operates them in a different way. You can check the details of the measure_timing function in evaluate.cpp from the official evaluator. Therefore, take a look at the modified version of OpenTimer in the third-party, from which the data report is closer to what the official evaluate produces (not the same of course, but enough for reference).

As for the simplest benchmark you are working on, it seems OpenTimer gives a wrong result given the first image. I believe it happened because OpenTimer failed to completely parse the input files. The file parsers of the two mentioned timers may behave very differently, even if we are talking about the same benchmark. You can find the toy case benchmark/simple from the official OpenTimer repo, and it must be a correct example OpenTimer can handle. Although the TAU'2015 toy case differs from ICCAD'2015 one, you can still check whether the early and late liberty files of these two simple benchmarks match. Besides, the .spef file you dump is also possible to be the key problem that OpenTimer failed to analyze.

I will see it. And thank you very much!

Hello, I find that the reason for the arrival time wrong using OpenTimer is that the “time_unit” in simple_Late.lib should be 1ps. Besides, I would like to inquire about the method of modifying impulse and load capacity using ratio_scale. I found that the update_interface_timing(const std::string&) function in the third-party library allows for 2-hop incremental analysis. However, the set_slew() and set_load() functions can only be applied to primary inputs (PI) and primary outputs (PO) respectively. How should I multiply the slew and load by ratio_scale on specified pins and perform incremental analysis? Thank you very much!

That would not be easy to discuss clearly in a sentence. If my understanding of your question is correct, there's a set_diffscale function as I remember, so you may directly perform update_interface_timing for a rough incremental analysis after setting the diffscale for surrounding (2-hop) pins, and see if you get the desired. So, there's no need to worry about internal timing variables. However, if you would like to do some tricks like what you said on your own, you may have to deal with the internal source code of OpenTimer and implement your own patch.