Skip to content

Commit f13c0af

Browse files
committed
cts: remove unused funtions that were moved from TritonCTS -> LatencyBalacer
Signed-off-by: arthurjolo <[email protected]>
1 parent 8ac411f commit f13c0af

File tree

7 files changed

+0
-396
lines changed

7 files changed

+0
-396
lines changed

src/cts/include/cts/TritonCTS.h

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -206,22 +206,6 @@ class TritonCTS
206206
void setAllClocksPropagated();
207207
void repairClockNets();
208208
void balanceMacroRegisterLatencies();
209-
float getVertexClkArrival(sta::Vertex* sinkVertex,
210-
odb::dbNet* topNet,
211-
odb::dbITerm* iterm);
212-
void computeAveSinkArrivals(TreeBuilder* builder, sta::Graph* graph);
213-
void computeSinkArrivalRecur(odb::dbNet* topClokcNet,
214-
odb::dbITerm* iterm,
215-
float& sumArrivals,
216-
unsigned& numSinks,
217-
sta::Graph* graph);
218-
bool propagateClock(odb::dbITerm* input);
219-
void adjustLatencies(TreeBuilder* macroBuilder, TreeBuilder* registerBuilder);
220-
void computeTopBufferDelay(TreeBuilder* builder);
221-
odb::dbInst* insertDelayBuffer(odb::dbInst* driver,
222-
const std::string& clockName,
223-
int locX,
224-
int locY);
225209

226210
sta::dbSta* openSta_ = nullptr;
227211
sta::dbNetwork* network_ = nullptr;

src/cts/src/TritonCTS.cpp

Lines changed: 0 additions & 354 deletions
Original file line numberDiff line numberDiff line change
@@ -2345,13 +2345,6 @@ void TritonCTS::printClockNetwork(const Clock& clockNet) const
23452345

23462346
void TritonCTS::setAllClocksPropagated()
23472347
{
2348-
// Compute ideal buffer delay to use in delay insertion
2349-
if (options_->insertionDelayEnabled()) {
2350-
for (auto& iter : builders_) {
2351-
TreeBuilder* builder = iter.get();
2352-
computeTopBufferDelay(builder);
2353-
}
2354-
}
23552348
sta::Sdc* sdc = openSta_->sdc();
23562349
for (sta::Clock* clk : *sdc->clocks()) {
23572350
openSta_->setPropagatedClock(clk);
@@ -2406,351 +2399,4 @@ void TritonCTS::balanceMacroRegisterLatencies()
24062399
}
24072400
}
24082401

2409-
float TritonCTS::getVertexClkArrival(sta::Vertex* sinkVertex,
2410-
odb::dbNet* topNet,
2411-
odb::dbITerm* iterm)
2412-
{
2413-
sta::VertexPathIterator pathIter(sinkVertex, openSta_);
2414-
float clkPathArrival = 0.0;
2415-
while (pathIter.hasNext()) {
2416-
sta::Path* path = pathIter.next();
2417-
const sta::ClockEdge* clock_edge = path->clkEdge(openSta_);
2418-
if (clock_edge == nullptr) {
2419-
continue;
2420-
}
2421-
2422-
if (clock_edge->transition() != sta::RiseFall::rise()) {
2423-
// only populate with rising edges
2424-
continue;
2425-
}
2426-
2427-
if (path->dcalcAnalysisPt(openSta_)->delayMinMax() != sta::MinMax::max()) {
2428-
continue;
2429-
// only populate with max delay
2430-
}
2431-
2432-
const sta::Clock* clock = path->clock(openSta_);
2433-
if (clock) {
2434-
sta::PathExpanded expand(path, openSta_);
2435-
const sta::Path* start = expand.startPath();
2436-
2437-
odb::dbNet* pathStartNet = nullptr;
2438-
2439-
odb::dbITerm* term;
2440-
odb::dbBTerm* port;
2441-
odb::dbModITerm* modIterm;
2442-
network_->staToDb(start->pin(openSta_), term, port, modIterm);
2443-
if (term) {
2444-
pathStartNet = term->getNet();
2445-
}
2446-
if (port) {
2447-
pathStartNet = port->getNet();
2448-
}
2449-
if (pathStartNet == topNet) {
2450-
clkPathArrival = path->arrival();
2451-
return clkPathArrival;
2452-
}
2453-
}
2454-
}
2455-
logger_->warn(CTS, 2, "No paths found for pin {}.", iterm->getName());
2456-
return clkPathArrival;
2457-
}
2458-
2459-
void TritonCTS::computeAveSinkArrivals(TreeBuilder* builder, sta::Graph* graph)
2460-
{
2461-
Clock clock = builder->getClock();
2462-
odb::dbNet* topInputClockNet = clock.getNetObj();
2463-
if (builder->getTopInputNet() != nullptr) {
2464-
topInputClockNet = builder->getTopInputNet();
2465-
}
2466-
// compute average input arrival at all sinks
2467-
float sumArrivals = 0.0;
2468-
unsigned numSinks = 0;
2469-
clock.forEachSink([&](const ClockInst& sink) {
2470-
odb::dbITerm* iterm = sink.getDbInputPin();
2471-
computeSinkArrivalRecur(
2472-
topInputClockNet, iterm, sumArrivals, numSinks, graph);
2473-
});
2474-
float aveArrival = sumArrivals / (float) numSinks;
2475-
builder->setAveSinkArrival(aveArrival);
2476-
debugPrint(logger_,
2477-
CTS,
2478-
"insertion delay",
2479-
1,
2480-
"{} {}: average sink arrival is {:0.3e}",
2481-
(builder->getTreeType() == TreeType::MacroTree) ? "macro tree"
2482-
: "register tree",
2483-
clock.getName(),
2484-
builder->getAveSinkArrival());
2485-
}
2486-
2487-
void TritonCTS::computeSinkArrivalRecur(odb::dbNet* topClokcNet,
2488-
odb::dbITerm* iterm,
2489-
float& sumArrivals,
2490-
unsigned& numSinks,
2491-
sta::Graph* graph)
2492-
{
2493-
if (iterm) {
2494-
odb::dbInst* inst = iterm->getInst();
2495-
if (inst) {
2496-
if (isSink(iterm)) {
2497-
// either register or macro input pin
2498-
sta::Pin* pin = network_->dbToSta(iterm);
2499-
if (pin) {
2500-
sta::Vertex* sinkVertex = graph->pinDrvrVertex(pin);
2501-
float arrival = getVertexClkArrival(sinkVertex, topClokcNet, iterm);
2502-
// add insertion delay
2503-
float insDelay = 0.0;
2504-
sta::LibertyCell* libCell
2505-
= network_->libertyCell(network_->dbToSta(inst));
2506-
odb::dbMTerm* mterm = iterm->getMTerm();
2507-
if (libCell && mterm) {
2508-
sta::LibertyPort* libPort
2509-
= libCell->findLibertyPort(mterm->getConstName());
2510-
if (libPort) {
2511-
const float rise = libPort->clkTreeDelay(
2512-
0.0, sta::RiseFall::rise(), sta::MinMax::max());
2513-
const float fall = libPort->clkTreeDelay(
2514-
0.0, sta::RiseFall::fall(), sta::MinMax::max());
2515-
2516-
if (rise != 0 || fall != 0) {
2517-
insDelay = (rise + fall) / 2.0;
2518-
}
2519-
}
2520-
}
2521-
sumArrivals += (arrival + insDelay);
2522-
numSinks++;
2523-
}
2524-
} else {
2525-
// not a sink, but a clock gater
2526-
odb::dbITerm* outTerm = inst->getFirstOutput();
2527-
if (outTerm) {
2528-
odb::dbNet* outNet = outTerm->getNet();
2529-
bool propagate = propagateClock(iterm);
2530-
if (outNet && propagate) {
2531-
odb::dbSet<odb::dbITerm> iterms = outNet->getITerms();
2532-
odb::dbSet<odb::dbITerm>::iterator iter;
2533-
for (iter = iterms.begin(); iter != iterms.end(); ++iter) {
2534-
odb::dbITerm* inTerm = *iter;
2535-
if (inTerm->getIoType() == odb::dbIoType::INPUT) {
2536-
computeSinkArrivalRecur(
2537-
topClokcNet, inTerm, sumArrivals, numSinks, graph);
2538-
}
2539-
}
2540-
}
2541-
}
2542-
}
2543-
}
2544-
}
2545-
}
2546-
2547-
bool TritonCTS::propagateClock(odb::dbITerm* input)
2548-
{
2549-
odb::dbInst* inst = input->getInst();
2550-
sta::Cell* masterCell = network_->dbToSta(inst->getMaster());
2551-
sta::LibertyCell* libertyCell = network_->libertyCell(masterCell);
2552-
2553-
if (!libertyCell) {
2554-
return false;
2555-
}
2556-
// Clock tree buffers
2557-
if (libertyCell->isInverter() || libertyCell->isBuffer()) {
2558-
return true;
2559-
}
2560-
// Combinational components
2561-
if (!libertyCell->hasSequentials()) {
2562-
return true;
2563-
}
2564-
sta::LibertyPort* inputPort
2565-
= libertyCell->findLibertyPort(input->getMTerm()->getConstName());
2566-
2567-
// Clock Gater / Latch improvised as clock gater
2568-
if (inputPort) {
2569-
return inputPort->isClockGateClock() || inputPort->isLatchData();
2570-
}
2571-
2572-
return false;
2573-
}
2574-
2575-
// Balance latencies between macro tree and register tree
2576-
// by adding delay buffers to one tree
2577-
void TritonCTS::adjustLatencies(TreeBuilder* macroBuilder,
2578-
TreeBuilder* registerBuilder)
2579-
{
2580-
float latencyDiff = macroBuilder->getAveSinkArrival()
2581-
- registerBuilder->getAveSinkArrival();
2582-
int numBuffers = 0;
2583-
TreeBuilder* builder = nullptr;
2584-
if (latencyDiff > 0) {
2585-
// add buffers to register tree
2586-
numBuffers = (int) (latencyDiff / registerBuilder->getTopBufferDelay());
2587-
builder = registerBuilder;
2588-
} else {
2589-
// add buffers to macro tree (not common but why not?)
2590-
numBuffers
2591-
= (int) (std::abs(latencyDiff) / macroBuilder->getTopBufferDelay());
2592-
builder = macroBuilder;
2593-
}
2594-
2595-
// We don't want to add more delay buffers than needed because
2596-
// wire delays are not considered. The fewer the delay buffers, the better.
2597-
numBuffers = numBuffers * options_->getDelayBufferDerate();
2598-
if (numBuffers == 0) {
2599-
// clang-format off
2600-
debugPrint(logger_, CTS, "insertion delay", 1, "no delay buffers are needed"
2601-
" to adjust latencies");
2602-
// clang-format on
2603-
return;
2604-
}
2605-
// clang-format off
2606-
debugPrint(logger_, CTS, "insertion delay", 1, "{} delay buffers are needed"
2607-
" to adjust latencies at {} tree", numBuffers,
2608-
(builder->getTreeType() == TreeType::MacroTree)? "macro" : "register");
2609-
// clang-format on
2610-
2611-
// disconnect driver output
2612-
odb::dbInst* driver = builder->getTopBuffer();
2613-
odb::dbITerm* driverOutputTerm = driver->getFirstOutput();
2614-
odb::dbNet* outputNet = driverOutputTerm->getNet();
2615-
2616-
// hierarchy support:
2617-
// Get the hierarchical net if any and propagate to end of chain
2618-
sta::Pin* op_pin = network_->dbToSta(driverOutputTerm);
2619-
odb::dbModNet* candidate_hier_net = network_->hasHierarchicalElements()
2620-
? network_->hierNet(op_pin)
2621-
: nullptr;
2622-
odb::dbNet* orig_flat_net = network_->flatNet(op_pin);
2623-
2624-
// get bbox of current load pins without driver output pin
2625-
driverOutputTerm->disconnect();
2626-
odb::Rect bbox = outputNet->getTermBBox();
2627-
int destX = bbox.xCenter();
2628-
int destY = bbox.yCenter();
2629-
int sourceX, sourceY;
2630-
driver->getLocation(sourceX, sourceY);
2631-
float offsetX = (float) (destX - sourceX) / (numBuffers + 1);
2632-
float offsetY = (float) (destY - sourceY) / (numBuffers + 1);
2633-
2634-
double scalingFactor = techChar_->getLengthUnit();
2635-
for (int i = 0; i < numBuffers; i++) {
2636-
double locX = (double) (sourceX + offsetX * (i + 1)) / scalingFactor;
2637-
double locY = (double) (sourceY + offsetY * (i + 1)) / scalingFactor;
2638-
Point<double> bufferLoc(locX, locY);
2639-
Point<double> legalBufferLoc
2640-
= builder->legalizeOneBuffer(bufferLoc, options_->getRootBuffer());
2641-
odb::dbInst* buffer
2642-
= insertDelayBuffer(driver,
2643-
builder->getClock().getSdcName(),
2644-
legalBufferLoc.getX() * scalingFactor,
2645-
legalBufferLoc.getY() * scalingFactor);
2646-
driver = buffer;
2647-
}
2648-
// take care of output pin connections
2649-
// driver is now the last delay buffer
2650-
driverOutputTerm = driver->getFirstOutput();
2651-
driverOutputTerm->disconnect();
2652-
// hierarchical fix. guarded by network has hierarchy
2653-
if (candidate_hier_net && network_->hasHierarchy()) {
2654-
network_->connectPin((sta::Pin*) driverOutputTerm,
2655-
(sta::Net*) orig_flat_net,
2656-
(sta::Net*) candidate_hier_net);
2657-
} else {
2658-
driverOutputTerm->connect(outputNet);
2659-
}
2660-
}
2661-
2662-
void TritonCTS::computeTopBufferDelay(TreeBuilder* builder)
2663-
{
2664-
Clock clock = builder->getClock();
2665-
odb::dbInst* topBuffer
2666-
= block_->findInst(builder->getTopBufferName().c_str());
2667-
if (topBuffer) {
2668-
builder->setTopBuffer(topBuffer);
2669-
odb::dbITerm* inputTerm = getFirstInput(topBuffer);
2670-
odb::dbITerm* outputTerm = topBuffer->getFirstOutput();
2671-
sta::Pin* inputPin = network_->dbToSta(inputTerm);
2672-
sta::Pin* outputPin = network_->dbToSta(outputTerm);
2673-
2674-
float inputArrival = openSta_->pinArrival(
2675-
inputPin, sta::RiseFall::rise(), sta::MinMax::max());
2676-
float outputArrival = openSta_->pinArrival(
2677-
outputPin, sta::RiseFall::rise(), sta::MinMax::max());
2678-
float bufferDelay = outputArrival - inputArrival;
2679-
// add a 10% increase on the buffer delay as this is an ideal model
2680-
// TODO: compute the exact delay adding a buffer adds,
2681-
// removing the need for the derate
2682-
builder->setTopBufferDelay(bufferDelay * 1.1);
2683-
debugPrint(logger_,
2684-
CTS,
2685-
"insertion delay",
2686-
1,
2687-
"top buffer delay for {} {} is {:0.3e}",
2688-
(builder->getTreeType() == TreeType::MacroTree)
2689-
? "macro tree"
2690-
: "register tree",
2691-
topBuffer->getName(),
2692-
builder->getTopBufferDelay());
2693-
}
2694-
}
2695-
2696-
// Create a new delay buffer and connect output pin of driver to input pin of
2697-
// new buffer. Output pin of new buffer will be connected later.
2698-
odb::dbInst* TritonCTS::insertDelayBuffer(odb::dbInst* driver,
2699-
const std::string& clockName,
2700-
int locX,
2701-
int locY)
2702-
2703-
{
2704-
// creat a new input net
2705-
std::string newNetName
2706-
= "delaynet_" + std::to_string(delayBufIndex_) + "_" + clockName;
2707-
2708-
// hierarchy fix, make the net in the right scope
2709-
odb::dbModule* module = driver->getModule();
2710-
if (module == nullptr) {
2711-
// if none put in top level
2712-
module = block_->getTopModule();
2713-
}
2714-
sta::Instance* scope
2715-
= (module == nullptr || (module == block_->getTopModule()))
2716-
? network_->topInstance()
2717-
: (sta::Instance*) (module->getModInst());
2718-
odb::dbNet* newNet = network_->staToDb(network_->makeNet(
2719-
newNetName.c_str(), scope, odb::dbNameUniquifyType::IF_NEEDED));
2720-
2721-
newNet->setSigType(odb::dbSigType::CLOCK);
2722-
2723-
// create a new delay buffer
2724-
std::string newBufName
2725-
= "delaybuf_" + std::to_string(delayBufIndex_++) + "_" + clockName;
2726-
odb::dbMaster* master = db_->findMaster(options_->getRootBuffer().c_str());
2727-
2728-
// fix: make buffer in same hierarchical module as driver
2729-
2730-
odb::dbInst* newBuf
2731-
= odb::dbInst::create(block_, master, newBufName.c_str(), false, module);
2732-
2733-
newBuf->setSourceType(odb::dbSourceType::TIMING);
2734-
newBuf->setLocation(locX, locY);
2735-
newBuf->setPlacementStatus(odb::dbPlacementStatus::PLACED);
2736-
2737-
// connect driver output with new buffer input
2738-
odb::dbITerm* driverOutTerm = driver->getFirstOutput();
2739-
odb::dbITerm* newBufInTerm = getFirstInput(newBuf);
2740-
2741-
driverOutTerm->disconnect();
2742-
driverOutTerm->connect(newNet);
2743-
newBufInTerm->connect(newNet);
2744-
2745-
debugPrint(logger_,
2746-
CTS,
2747-
"insertion delay",
2748-
1,
2749-
"new delay buffer {} is inserted at ({} {})",
2750-
newBuf->getName(),
2751-
locX,
2752-
locY);
2753-
2754-
return newBuf;
2755-
}
27562402
} // namespace cts

src/cts/test/gated_clock1.ok

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,6 @@
130130
[INFO CTS-0101] Average sink wire length 83.63 um
131131
[INFO CTS-0102] Path depth 2 - 2
132132
[INFO CTS-0207] Leaf load cells 29
133-
[DEBUG CTS-insertion delay] top buffer delay for macro tree clkbuf_0_clk is 2.480e-11
134-
[DEBUG CTS-insertion delay] top buffer delay for register tree clkbuf_regs_0_clk is 2.480e-11
135-
[DEBUG CTS-insertion delay] top buffer delay for register tree clkbuf_0_gclk1 is 5.007e-11
136133
[INFO CTS-0033] Balancing latency for clock clk
137134
[DEBUG CTS-insertion delay] new delay buffer delaybuf_0_clk is inserted at (101013 149105)
138135
[DEBUG CTS-insertion delay] new delay buffer delaybuf_1_clk is inserted at (102026 98350)

0 commit comments

Comments
 (0)