Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/database/data/design/IdbEnum.h
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,7 @@ enum class IdbLayerSpacingType : uint8_t
kSpacingDefault,
kSpacingRange,
kSpacingRangeLenThreshold,
kSpacingEndOfLine,
//!-----tbd-------------
kMax
};
Expand Down
30 changes: 30 additions & 0 deletions src/database/data/design/db_layout/IdbLayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,24 @@ class IdbLayerSpacing
const int32_t get_min_spacing() const { return _min_spacing; }
const int32_t get_min_width() const { return _min_width; }
const int32_t get_max_width() const { return _max_width; }
const int32_t get_eol_width() const { return _eol_width; }
const int32_t get_eol_within() const { return _eol_within; }
const bool get_has_parallel_edge() const { return _has_parallel_edge; }
const int32_t get_par_space() const { return _par_space; }
const int32_t get_par_within() const { return _par_within; }
const bool get_has_two_edges() const { return _has_two_edges; }

// setter
void set_spacing_type(IdbLayerSpacingType spacing_type) { _spacing_type = spacing_type; }
void set_min_spacing(int32_t min_spacing) { _min_spacing = min_spacing; }
void set_min_width(int32_t min_width) { _min_width = min_width; }
void set_max_width(int32_t max_width) { _max_width = max_width; }
void set_eol_width(int32_t eol_width) { _eol_width = eol_width; }
void set_eol_within(int32_t eol_within) { _eol_within = eol_within; }
void set_has_parallel_edge(bool has_parallel_edge) { _has_parallel_edge = has_parallel_edge; }
void set_par_space(int32_t par_space) { _par_space = par_space; }
void set_par_within(int32_t par_within) { _par_within = par_within; }
void set_has_two_edges(bool has_two_edges) { _has_two_edges = has_two_edges; }

// operator
bool isDefault() { return _spacing_type == IdbLayerSpacingType::kSpacingDefault ? true : false; }
Expand All @@ -126,6 +138,14 @@ class IdbLayerSpacing
int32_t _min_spacing;
int32_t _min_width;
int32_t _max_width;

// end of line
int32_t _eol_width;
int32_t _eol_within;
bool _has_parallel_edge;
int32_t _par_space;
int32_t _par_within;
bool _has_two_edges;
};

class IdbLayerSpacingList
Expand Down Expand Up @@ -343,6 +363,7 @@ class IdbLayerRouting : public IdbLayer
std::vector<std::shared_ptr<routinglayer::Lef58SpacingEol>>& get_lef58_spacing_eol_list() { return _lef58_spacing_eol_list; };
std::vector<std::shared_ptr<routinglayer::Lef58Area>>& get_lef58_area() { return _lef58_area; }
std::shared_ptr<routinglayer::Lef58CornerFillSpacing> get_lef58_corner_fill_spacing() { return _lef58_corner_fill_spacing; }
std::vector<std::shared_ptr<routinglayer::Lef58CornerSpacing>>& get_lef58_corner_spacing_list() { return _lef58_corner_spacing_list; }
std::vector<std::shared_ptr<routinglayer::Lef58MinimumCut>>& get_lef58_minimum_cut() { return _lef58_minimum_cut; }
std::vector<std::shared_ptr<routinglayer::Lef58MinStep>>& get_lef58_min_step() { return _lef58_min_steps; }
std::shared_ptr<routinglayer::Lef58SpacingNotchlength> get_lef58_spacing_notchlength() { return _lef58_spacing_notchlength; }
Expand Down Expand Up @@ -392,6 +413,10 @@ class IdbLayerRouting : public IdbLayer
{
_lef58_corner_fill_spacing = std::move(cornerfill_spacing);
}
void add_lef58_corner_spacing(std::shared_ptr<routinglayer::Lef58CornerSpacing> corner_spacing)
{
_lef58_corner_spacing_list.emplace_back(std::move(corner_spacing));
}
void add_lef58_minimum_cut(std::shared_ptr<routinglayer::Lef58MinimumCut> minimum_cut)
{
_lef58_minimum_cut.push_back(std::move(minimum_cut));
Expand Down Expand Up @@ -443,6 +468,7 @@ class IdbLayerRouting : public IdbLayer
std::vector<std::shared_ptr<routinglayer::Lef58SpacingEol>> _lef58_spacing_eol_list;
std::vector<std::shared_ptr<routinglayer::Lef58Area>> _lef58_area;
std::shared_ptr<routinglayer::Lef58CornerFillSpacing> _lef58_corner_fill_spacing;
std::vector<std::shared_ptr<routinglayer::Lef58CornerSpacing>> _lef58_corner_spacing_list;
std::vector<std::shared_ptr<routinglayer::Lef58MinimumCut>> _lef58_minimum_cut;
std::vector<std::shared_ptr<routinglayer::Lef58MinStep>> _lef58_min_steps;
std::shared_ptr<routinglayer::Lef58SpacingNotchlength> _lef58_spacing_notchlength;
Expand Down Expand Up @@ -556,9 +582,13 @@ class IdbLayerCutSpacing
void set_adjacent_cuts(std::optional<AdjacentCuts> adj) { _adjacnet_cuts = adj; }
[[nodiscard]] std::optional<AdjacentCuts> get_adjacent_cuts() const { return _adjacnet_cuts; }

void set_has_same_net(bool has_same_net) { _has_same_net = has_same_net; };
[[nodiscard]] bool get_has_same_net() const { return _has_same_net; }

private:
int32_t _spacing;
std::optional<AdjacentCuts> _adjacnet_cuts;
bool _has_same_net;
};

class IdbLayerCut : public IdbLayer
Expand Down
6 changes: 6 additions & 0 deletions src/database/data/design/db_layout/IdbLayer_routing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ IdbLayerSpacing::IdbLayerSpacing()
_min_spacing = -1;
_min_width = -1;
_max_width = -1;
_eol_width = -1;
_eol_within = -1;
_has_parallel_edge = false;
_par_space = -1;
_par_within = -1;
_has_two_edges = false;
}
IdbLayerSpacing::~IdbLayerSpacing()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,51 @@ class Lef58CornerFillSpacing
int32_t _eol_width;
};

// LEF58_CORNERSPACING
class Lef58CornerSpacing
{
public:
enum class CornerType
{
kNone,
kConvexCorner,
kConcaveCorner
};

class WidthSpacing
{
public:
WidthSpacing() = default;
WidthSpacing(int32_t width, int32_t spacing) : _width(width), _spacing(spacing) {}

[[nodiscard]] int32_t get_width() const { return _width; }
[[nodiscard]] int32_t get_spacing() const { return _spacing; }
void set_width(int32_t width) { _width = width; }
void set_spacing(int32_t spacing) { _spacing = spacing; }

private:
int32_t _width;
int32_t _spacing;
};

[[nodiscard]] CornerType get_corner_type() const { return _corner_type; }
[[nodiscard]] std::optional<int32_t> get_except_eol() const { return _except_eol; }
[[nodiscard]] const std::vector<WidthSpacing>& get_width_spacing_list() const { return _width_spacing_list; }

void set_corner_type(CornerType corner_type) { _corner_type = corner_type; }
void set_except_eol(int32_t except_eol) { _except_eol = except_eol; }
template <typename... Args>
void add_width_spacing(Args&&... args)
{
_width_spacing_list.emplace_back(std::forward<Args>(args)...);
}

private:
CornerType _corner_type = CornerType::kNone;
std::optional<int32_t> _except_eol;
std::vector<WidthSpacing> _width_spacing_list;
};

// LEF58_MINIMUMCUT
class Lef58MinimumCut
{
Expand Down
14 changes: 14 additions & 0 deletions src/database/manager/builder/lef_builder/lef_read.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,7 @@ int LefRead::parse_layer_cut(lefiLayer* lef_layer, IdbLayerCut* layer_cut)
double cut_within = lef_layer->spacingAdjacentWithin(i);
spacing->set_adjacent_cuts(IdbLayerCutSpacing::AdjacentCuts(adj_cuts, transUnitDB(cut_within)));
}
spacing->set_has_same_net(lef_layer->hasSpacingSamenet(i));
layer_cut->add_spacing(spacing);
}

Expand Down Expand Up @@ -670,6 +671,19 @@ int LefRead::parse_layer_routing(lefiLayer* lef_layer, IdbLayerRouting* layer_ro
auto& spacing_notch = layer_routing->get_spacing_notchlength();
spacing_notch.set_notch_length(transUnitDB(lef_layer->spacingNotchLength(i)));
spacing_notch.set_min_spacing(transUnitDB(lef_layer->spacing(i)));
// 如果有notchLength关键字,不能再算作Spacing规则
continue;
}
if (lef_layer->hasSpacingEndOfLine(i)) {
layer_spacing->set_spacing_type(IdbLayerSpacingType::kSpacingEndOfLine);
layer_spacing->set_eol_width(transUnitDB(lef_layer->spacingEolWidth(i)));
layer_spacing->set_eol_within(transUnitDB(lef_layer->spacingEolWithin(i)));
layer_spacing->set_has_parallel_edge(lef_layer->hasSpacingParellelEdge(i));
if (layer_spacing->get_has_parallel_edge()) {
layer_spacing->set_par_space(transUnitDB(lef_layer->spacingParSpace(i)));
layer_spacing->set_par_within(transUnitDB(lef_layer->spacingParWithin(i)));
layer_spacing->set_has_two_edges(lef_layer->hasSpacingTwoEdges(i));
}
}
spacing_list->add_spacing(layer_spacing);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,25 @@ struct lef58_spacingtable_jogtojog
std::vector<lef58_spacingtable_jogtojog_width> _width;
};

//////////////////////////////////
// LEF58_CORNERSPACING //
//////////////////////////////////

struct lef58_cornerspacing_width
{
double _width;
double _spacing;
};

struct lef58_cornerspacing
{
std::string _corner_type;
std::optional<double> _except_eol;
std::vector<lef58_cornerspacing_width> _width_spacings;
};



} // namespace idb::routinglayer_property

BOOST_FUSION_ADAPT_STRUCT(idb::routinglayer_property::double_pair, (double, first)(double, second))
Expand Down Expand Up @@ -322,4 +341,8 @@ BOOST_FUSION_ADAPT_STRUCT(idb::routinglayer_property::lef58_spacingtable_jogtojo
_width_short_jog_spacing))
BOOST_FUSION_ADAPT_STRUCT(idb::routinglayer_property::lef58_spacingtable_jogtojog,
(double, _jog2jog_spacing)(double, _jog_width)(double, _short_jog_spacing)(
std::vector<idb::routinglayer_property::lef58_spacingtable_jogtojog_width>, _width))
std::vector<idb::routinglayer_property::lef58_spacingtable_jogtojog_width>, _width))
BOOST_FUSION_ADAPT_STRUCT(idb::routinglayer_property::lef58_cornerspacing_width, (double, _width)(double, _spacing))
BOOST_FUSION_ADAPT_STRUCT(idb::routinglayer_property::lef58_cornerspacing,
(std::string, _corner_type)(std::optional<double>, _except_eol)(
std::vector<idb::routinglayer_property::lef58_cornerspacing_width>, _width_spacings))
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ namespace idb::routinglayer_property {
template<typename Iterator>
bool parse_lef58_conerfillspacing(Iterator beg, Iterator end, lef58_cornerfillspacing& spacing);

template<typename Iterator>
bool parse_lef58_cornerspacing(Iterator beg, Iterator end, std::vector<lef58_cornerspacing>& spacings);

template<typename Iterator>
bool parse_lef58_minimumcut(Iterator beg, Iterator end, std::vector<lef58_minimumcut>& cuts);

Expand Down Expand Up @@ -72,6 +75,25 @@ namespace idb::routinglayer_property {
return true;
}

template<typename Iterator>
bool parse_lef58_cornerspacing(Iterator beg, Iterator end, std::vector<lef58_cornerspacing>& spacings) {
const static qi::rule<Iterator, lef58_cornerspacing_width(), space_type> width_spacing_rule =
lit("WIDTH") >> double_ >> lit("SPACING") >> double_;
const static qi::rule<Iterator, lef58_cornerspacing(), space_type> corner_spacing_rule =
lit("CORNERSPACING")
>> (qi::string("CONVEXCORNER") | qi::string("CONCAVECORNER"))
>> -(lit("EXCEPTEOL") >> double_)
>> +width_spacing_rule
>> lit(";");

bool ok = qi::phrase_parse(beg, end, +corner_spacing_rule, space, spacings);
if (!ok || beg != end) {
std::cout << "Parse \"" << std::string(beg, end) << "\" failed" << std::endl;
return false;
}
return true;
}

template<typename Iterator>
bool parse_lef58_minimumcut(Iterator beg, Iterator end, std::vector<lef58_minimumcut>& cuts){
const static qi::rule<Iterator, std::string(), ascii::space_type> value_string = lexeme[+(char_ - char_(" ;\n"))];
Expand Down Expand Up @@ -221,4 +243,4 @@ namespace idb::routinglayer_property {
}
return true;
}
} // namespace idb::routinglayer_property
} // namespace idb::routinglayer_property
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,43 @@ TEST(RoutingLayerTest, LEF58CORNERFILLSPACING) {
EXPECT_EQ(spacing._eol_width, 0.06);
}

TEST(RoutingLayerTest, LEF58CORNERSPACINGMultipleRules) {
std::vector<lef58_cornerspacing> spacings;
const std::string str = R"(
CORNERSPACING CONVEXCORNER EXCEPTEOL 0.08
WIDTH 0.00 SPACING 0.10
WIDTH 0.20 SPACING 0.20
WIDTH 0.50 SPACING 0.30 ;
CORNERSPACING CONCAVECORNER
WIDTH 0.00 SPACING 0.12
WIDTH 0.18 SPACING 0.22 ;)";

bool ok = parse_lef58_cornerspacing(str.begin(), str.end(), spacings);
EXPECT_TRUE(ok);
ASSERT_EQ(spacings.size(), 2);

const auto& convex_spacing = spacings[0];
EXPECT_EQ(convex_spacing._corner_type, "CONVEXCORNER");
EXPECT_TRUE(convex_spacing._except_eol.has_value());
EXPECT_EQ(convex_spacing._except_eol.value(), 0.08);
EXPECT_EQ(convex_spacing._width_spacings.size(), 3);
EXPECT_EQ(convex_spacing._width_spacings[0]._width, 0.00);
EXPECT_EQ(convex_spacing._width_spacings[0]._spacing, 0.10);
EXPECT_EQ(convex_spacing._width_spacings[1]._width, 0.20);
EXPECT_EQ(convex_spacing._width_spacings[1]._spacing, 0.20);
EXPECT_EQ(convex_spacing._width_spacings[2]._width, 0.50);
EXPECT_EQ(convex_spacing._width_spacings[2]._spacing, 0.30);

const auto& concave_spacing = spacings[1];
EXPECT_EQ(concave_spacing._corner_type, "CONCAVECORNER");
EXPECT_FALSE(concave_spacing._except_eol.has_value());
EXPECT_EQ(concave_spacing._width_spacings.size(), 2);
EXPECT_EQ(concave_spacing._width_spacings[0]._width, 0.00);
EXPECT_EQ(concave_spacing._width_spacings[0]._spacing, 0.12);
EXPECT_EQ(concave_spacing._width_spacings[1]._width, 0.18);
EXPECT_EQ(concave_spacing._width_spacings[1]._spacing, 0.22);
}

TEST(RoutingLayerTest, LEF58MINIMUNCUT) {
std::vector<lef58_minimumcut> cuts;
const std::string str = R"(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ bool RoutingLayerParser::parse(const std::string& name, const std::string& value
if (name == "LEF58_CORNERFILLSPACING") {
return parse_lef58_conerfillspacing(value, data);
}
if (name == "LEF58_CORNERSPACING") {
return parse_lef58_cornerspacing(value, data);
}
if (name == "LEF58_MINIMUMCUT") {
return parse_lef58_minimuncut(value, data);
}
Expand Down Expand Up @@ -95,6 +98,34 @@ bool RoutingLayerParser::parse_lef58_conerfillspacing(const std::string& value,
cornerfill_spacing->set_eol_width(transUnitDB(cornerspacing._eol_width));
return true;
}
bool RoutingLayerParser::parse_lef58_cornerspacing(const std::string& value, IdbLayerRouting* data)
{
std::vector<routinglayer_property::lef58_cornerspacing> cornerspacings;
bool parse_ok = routinglayer_property::parse_lef58_cornerspacing(value.begin(), value.end(), cornerspacings);
if (not parse_ok) {
return false;
}

for (const auto& cornerspacing : cornerspacings) {
auto corner_spacing = std::make_shared<routinglayer::Lef58CornerSpacing>();
data->add_lef58_corner_spacing(corner_spacing);

if (cornerspacing._corner_type == "CONVEXCORNER") {
corner_spacing->set_corner_type(routinglayer::Lef58CornerSpacing::CornerType::kConvexCorner);
} else if (cornerspacing._corner_type == "CONCAVECORNER") {
corner_spacing->set_corner_type(routinglayer::Lef58CornerSpacing::CornerType::kConcaveCorner);
}

if (cornerspacing._except_eol.has_value()) {
corner_spacing->set_except_eol(transUnitDB(cornerspacing._except_eol.value()));
}

for (const auto& width_spacing : cornerspacing._width_spacings) {
corner_spacing->add_width_spacing(transUnitDB(width_spacing._width), transUnitDB(width_spacing._spacing));
}
}
return true;
}
bool RoutingLayerParser::parse_lef58_minimuncut(const std::string& value, IdbLayerRouting* data)
{
std::vector<routinglayer_property::lef58_minimumcut> minimuncuts;
Expand Down Expand Up @@ -303,4 +334,4 @@ bool RoutingLayerParser::parse_lef58_spacingtable(const std::string& value, IdbL
return false;
}

} // namespace idb
} // namespace idb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class RoutingLayerParser : public PropertyBaseParser<IdbLayerRouting>
private:
bool parse_lef58_area(const std::string& value, IdbLayerRouting* data);
bool parse_lef58_conerfillspacing(const std::string& value, IdbLayerRouting* data);
bool parse_lef58_cornerspacing(const std::string& value, IdbLayerRouting* data);
bool parse_lef58_minimuncut(const std::string& value, IdbLayerRouting* data);
bool parse_lef58_minstep(const std::string& value, IdbLayerRouting* data);
bool parse_lef58_spacing(const std::string& value, IdbLayerRouting* data);
Expand Down
Loading