Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Odb defin scan parse fix #6587

Merged
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
32 changes: 16 additions & 16 deletions src/dft/test/scan_inserted_design_sky130.scandef
Original file line number Diff line number Diff line change
Expand Up @@ -17,71 +17,71 @@ SCANCHAINS 9 ;
+ STOP PIN output1 ;

- chain_1_0
+ START PIN ff10_clk2_falling/SCD
+ START ff10_clk2_falling SCD
+ FLOATING
ff10_clk2_falling ( IN SCD ) ( OUT Q )
ff4_clk2_falling ( IN SCD ) ( OUT Q )
+ PARTITION main_clock_falling
+ STOP PIN ff4_clk2_falling/Q ;
+ STOP ff4_clk2_falling Q ;

- chain_1_1
+ START PIN ff10_clk2_rising/SCD
+ START ff10_clk2_rising SCD
+ FLOATING ff10_clk2_rising ( IN SCD ) ( OUT Q )
+ PARTITION main_clock_rising
+ STOP PIN ff10_clk2_rising/Q ;
+ STOP ff10_clk2_rising Q ;

- chain_2
+ START PIN ff8_clk2_rising/SCD
+ START ff8_clk2_rising SCD
+ FLOATING
ff8_clk2_rising ( IN SCD ) ( OUT Q )
ff2_clk2_rising ( IN SCD ) ( OUT Q )
+ ORDERED
iso ( IN A ) ( OUT X )
ff6_clk2_rising ( IN SCD ) ( OUT Q )
+ PARTITION main_clock_rising
+ STOP PIN ff6_clk2_rising/SCD ;
+ STOP ff6_clk2_rising SCD ;

- chain_3_0
+ COMMONSCANPINS ( IN SCD ) ( OUT Q )
+ START PIN ff1_clk1_falling/SCD
+ START ff1_clk1_falling SCD
+ FLOATING
ff1_clk1_falling
ff3_clk1_falling
+ PARTITION main_clock_falling
+ STOP PIN ff3_clk1_falling/SCD ;
+ STOP ff3_clk1_falling SCD ;

- chain_3_1
+ START PIN ff4_clk2_rising/SCD
+ START ff4_clk2_rising SCD
+ FLOATING ff4_clk2_rising ( IN SCD ) ( OUT Q )
+ PARTITION main_clock_rising
+ STOP PIN ff4_clk2_rising/Q ;
+ STOP ff4_clk2_rising Q ;

- chain_4
+ START PIN ff7_clk1_falling/SCD
+ START ff7_clk1_falling SCD
+ FLOATING
ff7_clk1_falling ( IN SCD ) ( OUT Q )
ff9_clk1_falling ( IN SCD ) ( OUT Q )
ff5_clk1_falling ( IN SCD ) ( OUT Q )
+ PARTITION main_clock_falling
+ STOP PIN ff5_clk1_falling/Q ;
+ STOP ff5_clk1_falling Q ;

- chain_5
+ START PIN ff3_clk1_rising/SCD
+ START ff3_clk1_rising SCD
+ COMMONSCANPINS ( IN SCD ) ( OUT Q )
+ FLOATING
ff3_clk1_rising
ff5_clk1_rising
ff7_clk1_rising
+ PARTITION main_clock_rising
+ STOP PIN ff7_clk1_rising/Q ;
+ STOP ff7_clk1_rising Q ;

- chain_6
+ START PIN ff1_clk1_rising/SCD
+ START ff1_clk1_rising SCD
+ FLOATING
ff1_clk1_rising ( IN SCD ) ( OUT Q )
ff9_clk1_rising ( IN SCD ) ( OUT Q )
+ PARTITION main_clock_rising
+ STOP PIN ff9_clk1_rising/Q ;
+ STOP ff9_clk1_rising Q ;


END SCANCHAINS
Expand Down
72 changes: 41 additions & 31 deletions src/odb/src/defin/definReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ dbITerm* findScanITerm(definReader* reader,
if (!pin_name) {
if (!common_pin) {
reader->error(
fmt::format("SCANDEF is missing either component pin or a "
fmt::format("SCANCHAIN is missing either component pin or a "
"COMMONSCANPINS for instance {}",
inst->getName()));
return nullptr;
Expand All @@ -114,20 +114,34 @@ dbITerm* findScanITerm(definReader* reader,
return inst->findITerm(pin_name);
}

std::optional<std::variant<dbBTerm*, dbITerm*>>
findScanTerm(definReader* reader, dbBlock* block, const char* pin_name)
std::optional<std::variant<dbBTerm*, dbITerm*>> findScanTerm(
definReader* reader,
dbBlock* block,
const char* type,
const char* inst_name,
const char* pin_name)
{
dbBTerm* bterm = block->findBTerm(pin_name);
if (bterm) {
return bterm;
if (inst_name && strcmp(inst_name, "PIN") != 0) {
dbInst* inst = block->findInst(inst_name);
if (inst) {
dbITerm* iterm = inst->findITerm(pin_name);
if (iterm) {
return iterm;
}
}
} else {
dbBTerm* bterm = block->findBTerm(pin_name);
if (bterm) {
return bterm;
}
}

dbITerm* iterm = block->findITerm(pin_name);
if (iterm) {
return iterm;
std::string name;
if (inst_name) {
name = fmt::format("{}/{}", inst_name, pin_name);
} else {
name = pin_name;
}
reader->error(
fmt::format("SCANDEF START/STOP pin {} does not exist", pin_name));
reader->error(fmt::format("SCANCHAIN {} pin {} does not exist", type, name));
return std::nullopt;
}

Expand All @@ -142,7 +156,7 @@ void populateScanInst(definReader* reader,
{
dbInst* inst = block->findInst(inst_name);
if (!inst) {
reader->error(fmt::format("SCANDEF Inst {} does not exist", inst_name));
reader->error(fmt::format("SCANCHAIN Inst {} does not exist", inst_name));
return;
}

Expand All @@ -151,14 +165,15 @@ void populateScanInst(definReader* reader,
dbITerm* scan_in
= findScanITerm(reader, inst, in_pin_name, scan_chain->commonInPin());
if (!scan_in) {
reader->error(fmt::format(
"SCANDEF IN pin {} does not exist in cell {}", in_pin_name, inst_name));
reader->error(fmt::format("SCANCHAIN IN pin {} does not exist in cell {}",
in_pin_name,
inst_name));
}

dbITerm* scan_out
= findScanITerm(reader, inst, out_pin_name, scan_chain->commonOutPin());
if (!scan_out) {
reader->error(fmt::format("SCANDEF OUT pin {} does not exist in cell {}",
reader->error(fmt::format("SCANCHAIN OUT pin {} does not exist in cell {}",
out_pin_name,
inst_name));
}
Expand Down Expand Up @@ -1446,23 +1461,18 @@ int definReader::scanchainsCallback(
dbScanPartition* db_scan_partition = dbScanPartition::create(db_scan_chain);
db_scan_partition->setName(scan_chain->partitionName());

char* unused;
char* start_inst_name;
char* stop_inst_name;
char* start_pin_name;
char* stop_pin_name;
scan_chain->start(&unused, &start_pin_name);
scan_chain->stop(&unused, &stop_pin_name);

auto scan_in_pin = findScanTerm(reader, block, start_pin_name);
auto scan_out_pin = findScanTerm(reader, block, stop_pin_name);
if (!scan_in_pin.has_value()) {
reader->error(fmt::format("Can't parse SCANIN pin"));
if (reader->_continue_on_errors) {
return PARSE_OK;
}
return PARSE_ERROR;
}
if (!scan_out_pin.has_value()) {
reader->error(fmt::format("Can't parse SCANOUT pin"));
scan_chain->start(&start_inst_name, &start_pin_name);
scan_chain->stop(&stop_inst_name, &stop_pin_name);

auto scan_in_pin
= findScanTerm(reader, block, "START", start_inst_name, start_pin_name);
auto scan_out_pin
= findScanTerm(reader, block, "STOP", stop_inst_name, stop_pin_name);
if (!scan_in_pin.has_value() || !scan_out_pin.has_value()) {
if (reader->_continue_on_errors) {
return PARSE_OK;
}
Expand Down
Loading