Skip to content

Commit 771b124

Browse files
authored
Merge pull request #287 from MarceloDanigno/cts_dbwrapper_update
[TritonCTS] Updated function to find clock nets
2 parents 47859fe + 54d8b1c commit 771b124

File tree

14 files changed

+417
-46
lines changed

14 files changed

+417
-46
lines changed

src/TritonCTS/src/CtsOptions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#define PARAMETERSFORCTS_H
4545

4646
#include "Util.h"
47+
#include "db.h"
4748

4849
#include <string>
4950
#include <iostream>
@@ -114,6 +115,8 @@ class CtsOptions {
114115
bool runPostCtsOpt() { return _runPostCtsOpt; }
115116
void setBufDistRatio(double ratio) { _bufDistRatio = ratio; }
116117
double getBufDistRatio() { return _bufDistRatio; }
118+
void setClockNetsObjs(std::vector<odb::dbNet*> nets) { _clockNetsObjs = nets; }
119+
std::vector<odb::dbNet*> getClockNetsObjs() const { return _clockNetsObjs; }
117120

118121
private:
119122
std::string _blockName = "";
@@ -146,6 +149,7 @@ class CtsOptions {
146149
double _bufDistRatio = 0.1;
147150

148151
std::vector<std::string> _bufferList;
152+
std::vector<odb::dbNet*> _clockNetsObjs;
149153
};
150154

151155
}

src/TritonCTS/src/DbWrapper.cpp

Lines changed: 50 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include "DbWrapper.h"
4444
#include "TritonCTSKernel.h"
4545
#include "HTreeBuilder.h"
46+
#include "db_sta/dbSta.hh"
4647

4748
// DB includes
4849
#include "db.h"
@@ -66,6 +67,8 @@ void DbWrapper::populateTritonCTS() {
6667
}
6768

6869
void DbWrapper::initDB() {
70+
ord::OpenRoad* openRoad = ord::OpenRoad::openRoad();
71+
_openSta = openRoad->getSta();
6972
_db = odb::dbDatabase::getDatabase(_options->getDbId());
7073
_chip = _db->getChip();
7174
_block = _chip->getBlock();
@@ -74,32 +77,50 @@ void DbWrapper::initDB() {
7477

7578
void DbWrapper::initAllClocks() {
7679
std::cout << " Initializing clock nets\n";
77-
78-
std::vector<std::string> clockNetNames;
79-
parseClockNames(clockNetNames);
80+
81+
clearNumClocks();
8082

8183
std::cout << " Looking for clock nets in the design\n";
82-
for (const std::string& name: clockNetNames) {
83-
odb::dbNet* net = _block->findNet(name.c_str());
84-
if (!net) {
85-
odb::dbITerm* iterm = _block->findITerm(name.c_str());
86-
net = iterm->getNet();
84+
85+
//Uses dbSta to find all clock nets in the design.
86+
87+
std::set<odb::dbNet*> clockNets;
88+
89+
_openSta->findClkNets(clockNets);
90+
91+
//Checks the user input in case there are other nets that need to be added to the set.
92+
std::vector<odb::dbNet*> inputClkNets = _options->getClockNetsObjs();
93+
94+
for (odb::dbNet* net : inputClkNets) {
95+
//Since a set is unique, only the nets not found by dbSta are added.
96+
clockNets.insert(net);
97+
}
98+
99+
//Iterate over all the nets found by the user-input and dbSta
100+
for (odb::dbNet* net : clockNets){
101+
if (net != nullptr) {
102+
std::cout << " Net \"" << net->getName() << "\" found\n";
103+
//Initializes the net in TritonCTS. If the number of sinks is less than 2, the net is discarded.
104+
initClock(net);
105+
} else {
106+
std::cout << " [WARNING] A net was not found in the design. Skipping...\n";
87107
}
88-
if (!net) {
89-
std::cout << " [WARNING] Net \"" << name << "\" not in design. Skipping...\n";
90-
continue;
91-
}
92-
93-
std::cout << " Net \"" << name << "\" found\n";
94-
initClock(net);
95108
}
109+
110+
if (getNumClocks() <= 0) {
111+
std::cout << "\n";
112+
std::cout << " [ERROR] No clock nets have been found.\n";
113+
std::exit(1);
114+
}
115+
116+
std::cout << " TritonCTS found " << getNumClocks() << " clock nets." << std::endl;
96117
}
97118

98119
void DbWrapper::initClock(odb::dbNet* net) {
99120
std::string driver = "";
100121
odb::dbITerm* iterm = net->getFirstOutput();
101122
int xPin, yPin;
102-
if (!iterm) {
123+
if (iterm == nullptr) {
103124
odb::dbBTerm* bterm = net->get1stBTerm(); // Clock pin
104125
driver = bterm->getConstName();
105126
bterm->getFirstPinLocation(xPin, yPin);
@@ -114,18 +135,15 @@ void DbWrapper::initClock(odb::dbNet* net) {
114135
}
115136

116137
// Initialize clock net
117-
std::cout << net->getConstName() << std::endl;
138+
std::cout << " Initializing clock net for : \"" << net->getConstName() << "\"" << std::endl;
118139

119140
Clock clockNet(net->getConstName(),
120141
driver,
121142
xPin, yPin);
122143

123-
odb::dbSet<odb::dbITerm> iterms = net->getITerms();
124-
odb::dbSet<odb::dbITerm>::iterator itr;
125-
for (itr = iterms.begin(); itr != iterms.end(); ++itr) {
126-
odb::dbITerm* iterm = *itr;
127-
128-
if (iterm->getIoType() != odb::dbIoType::INPUT) {
144+
for (odb::dbITerm* iterm : net->getITerms()) {
145+
146+
if (!(iterm->isInputSignal())) {
129147
continue;
130148
}
131149

@@ -145,6 +163,10 @@ void DbWrapper::initClock(odb::dbNet* net) {
145163

146164
}
147165

166+
std::cout << " Clock net \"" << net->getConstName() << "\" has " << clockNet.getNumSinks() << " sinks" << std::endl;
167+
168+
incrementNumClocks();
169+
148170
_kernel->addBuilder(new HTreeBuilder(*_options, clockNet));
149171
}
150172

@@ -157,19 +179,14 @@ void DbWrapper::parseClockNames(std::vector<std::string>& clockNetNames) const {
157179
}
158180

159181
unsigned numClocks = clockNetNames.size();
160-
std::cout << " Number of user-input clocks: " << numClocks;
182+
std::cout << " Number of user-input clocks: " << numClocks << ".\n";
161183

162184
if (numClocks > 0) {
163185
std::cout << " (";
164186
for (const std::string& name: clockNetNames) {
165187
std::cout << " \"" << name << "\"";
166188
}
167189
std::cout << " )\n";
168-
} else {
169-
std::cout << "\n";
170-
std::cout << " [ERROR] No clock nets have been found.\n";
171-
std::exit(1);
172-
173190
}
174191
}
175192

@@ -189,9 +206,10 @@ void DbWrapper::computeITermPosition(odb::dbITerm* term, DBU &x, DBU &y) const {
189206
++numShapes;
190207
}
191208
}
192-
193-
x /= numShapes;
194-
y /= numShapes;
209+
if (numShapes > 0){
210+
x /= numShapes;
211+
y /= numShapes;
212+
}
195213
};
196214

197215
void DbWrapper::writeClockNetsToDb(const Clock& clockNet) {

src/TritonCTS/src/DbWrapper.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,18 @@ class DbWrapper {
7272
void populateTritonCTS();
7373
void writeClockNetsToDb(const Clock& clockNet);
7474

75+
void incrementNumClocks() { _numberOfClocks = _numberOfClocks + 1; }
76+
void clearNumClocks() { _numberOfClocks = 0; }
77+
unsigned getNumClocks() const { return _numberOfClocks; }
78+
7579
private:
76-
odb::dbDatabase* _db = nullptr;
77-
odb::dbChip* _chip = nullptr;
78-
odb::dbBlock* _block = nullptr;
79-
CtsOptions* _options = nullptr;
80-
TritonCTSKernel* _kernel = nullptr;
80+
sta::dbSta* _openSta = nullptr;
81+
odb::dbDatabase* _db = nullptr;
82+
odb::dbChip* _chip = nullptr;
83+
odb::dbBlock* _block = nullptr;
84+
CtsOptions* _options = nullptr;
85+
TritonCTSKernel* _kernel = nullptr;
86+
unsigned _numberOfClocks = 0;
8187

8288
void parseClockNames(std::vector<std::string>& clockNetNames) const;
8389

src/TritonCTS/src/TritonCTSKernel.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,6 @@ void TritonCTSKernel::setupCharacterization() {
7878
//LUT files exists. Import the characterization results.
7979
importCharacterization();
8080
}
81-
if (_options.getOnlyCharacterization() == true){
82-
std::exit(1);
83-
}
8481
}
8582

8683
void TritonCTSKernel::importCharacterization() {
@@ -124,6 +121,11 @@ void TritonCTSKernel::checkCharacterization() {
124121

125122
std::cout << " The chacterization used " << visitedMasters.size() << " buffer(s) types."
126123
<< " All of them are in the loaded DB.\n";
124+
125+
126+
if (_options.getOnlyCharacterization() == true){
127+
std::exit(1);
128+
}
127129
}
128130

129131
void TritonCTSKernel::findClockRoots() {
@@ -138,9 +140,7 @@ void TritonCTSKernel::findClockRoots() {
138140
}
139141

140142
std::cout << " User did not specify clock roots.\n";
141-
std::cout << " Using OpenSTA to find clock roots.\n";
142143
_staEngine.init();
143-
_staEngine.findClockRoots();
144144
}
145145

146146
void TritonCTSKernel::populateTritonCts() {

src/TritonCTS/src/TritonCTSKernel.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ class TritonCTSKernel {
9393
void export_characterization(const char* file);
9494
void set_root_buffer(const char* buffer);
9595
void set_buffer_list(const char* buffers);
96-
void set_clock_nets(const char* names);
96+
int set_clock_nets(const char* names);
9797
void set_wire_segment_distance_unit(unsigned unit);
9898
void set_max_char_slew(double slew);
9999
void set_max_char_cap(double cap);

src/TritonCTS/src/TritonCTSKernelTcl.cpp

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@
4242

4343
#include "TritonCTSKernel.h"
4444

45+
// DB includes
46+
#include "db.h"
47+
4548
#include <iostream>
4649
#include <iterator>
4750
#include <sstream>
@@ -61,8 +64,45 @@ void TritonCTSKernel::set_sol_list_file(const char* file) {
6164
_options.setSolListFile(file);
6265
}
6366

64-
void TritonCTSKernel::set_clock_nets(const char* names) {
67+
int TritonCTSKernel::set_clock_nets(const char* names) {
68+
odb::dbDatabase* db = odb::dbDatabase::getDatabase(_options.getDbId());
69+
odb::dbChip* chip = db->getChip();
70+
odb::dbBlock* block = chip->getBlock();
71+
6572
_options.setClockNets(names);
73+
std::stringstream ss(names);
74+
std::istream_iterator<std::string> begin(ss);
75+
std::istream_iterator<std::string> end;
76+
std::vector<std::string> nets(begin, end);
77+
78+
std::vector<odb::dbNet*> netObjects;
79+
80+
for (std::string name : nets){
81+
odb::dbNet* net = block->findNet(name.c_str());
82+
bool netFound = false;
83+
if (net != nullptr) {
84+
//Since a set is unique, only the nets not found by dbSta are added.
85+
netObjects.push_back(net);
86+
netFound = true;
87+
} else {
88+
//User input was a pin, transform it into an iterm if possible
89+
odb::dbITerm* iterm = block->findITerm(name.c_str());
90+
if (iterm != nullptr) {
91+
net = iterm->getNet();
92+
if (net != nullptr) {
93+
//Since a set is unique, only the nets not found by dbSta are added.
94+
netObjects.push_back(net);
95+
netFound = true;
96+
}
97+
}
98+
99+
}
100+
if (!netFound) {
101+
return 1;
102+
}
103+
}
104+
_options.setClockNetsObjs(netObjects);
105+
return 0;
66106
}
67107

68108
void TritonCTSKernel::set_max_char_cap(double cap) {

src/TritonCTS/src/tritoncts.tcl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,11 @@ proc clock_tree_synthesis { args } {
113113

114114
if { [info exists keys(-clk_nets)] } {
115115
set clk_nets $keys(-clk_nets)
116-
$cts set_clock_nets $clk_nets
116+
set fail [$cts set_clock_nets $clk_nets]
117+
if {$fail} {
118+
puts "Error when finding -clk_nets in DB!"
119+
exit
120+
}
117121
}
118122

119123
if { [info exists keys(-slew_inter)] } {

src/TritonCTS/test/regression

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ do
3131
fi
3232

3333
cd $unit_test_path
34+
ln -s $testdir/../../../test/Nangate45
3435
$test_script $binary
36+
unlink Nangate45
3537
test_return_code=$?
3638
cd $test_root
3739

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
VERSION 5.8 ;
2+
NAMESCASESENSITIVE ON ;
3+
DIVIDERCHAR "/" ;
4+
BUSBITCHARS "[]" ;
5+
6+
DESIGN top ;
7+
8+
UNITS DISTANCE MICRONS 1000 ;
9+
10+
DIEAREA ( 0 0 ) ( 1000 1000 ) ;
11+
12+
COMPONENTS 5 ;
13+
- r1 DFF_X1 ;
14+
- r2 DFF_X1 ;
15+
- u1 BUF_X1 ;
16+
- p1 PAD ;
17+
END COMPONENTS
18+
19+
PINS 6 ;
20+
- in1 + NET in1 + DIRECTION INPUT ;
21+
- clk1 + NET clk1 + DIRECTION INPUT ;
22+
- out1 + NET out + DIRECTION OUTPUT ;
23+
END PINS
24+
25+
SPECIALNETS 2 ;
26+
- VSS ( * VSS )
27+
+ USE GROUND ;
28+
- VDD ( * VDD )
29+
+ USE POWER ;
30+
END SPECIALNETS
31+
32+
NETS 10 ;
33+
- in1 ( PIN in1 ) ( r1 D ) ;
34+
- clk1 ( PIN clk1 ) ( p1 PAD ) ;
35+
- clk2 ( p1 Y ) ( r1 CK ) ( r2 CK ) ;
36+
- r1q ( r1 Q ) ( u1 A ) ;
37+
- u1z ( u1 Z ) ( r2 D ) ;
38+
- out1 ( r2 Q ) ( PIN out1 ) ;
39+
END NETS
40+
41+
END DESIGN

0 commit comments

Comments
 (0)