@@ -431,6 +431,16 @@ class LatchInst : public Instance {
431
431
return is;
432
432
}
433
433
434
+ private:
435
+ std::string type_to_sdf_edge () {
436
+ if (type_ == Type::RISING_EDGE)
437
+ return " posedge" ;
438
+ else if (type_ == Type::FALLING_EDGE)
439
+ return " negedge" ;
440
+ else
441
+ VTR_ASSERT (false );
442
+ }
443
+
434
444
public:
435
445
LatchInst (std::string inst_name, // /<Name of this instance
436
446
std::map<std::string, std::string> port_conns, // /<Instance's port-to-net connections
@@ -474,7 +484,7 @@ class LatchInst : public Instance {
474
484
475
485
void print_verilog (std::ostream& os, size_t & /* unconn_count*/ , int depth = 0 ) override {
476
486
// Currently assume a standard DFF
477
- VTR_ASSERT (type_ == Type::RISING_EDGE);
487
+ VTR_ASSERT (type_ == Type::RISING_EDGE || type_ == Type::FALLING_EDGE );
478
488
479
489
os << indent (depth) << " DFF"
480
490
<< " #(\n " ;
@@ -505,7 +515,7 @@ class LatchInst : public Instance {
505
515
}
506
516
507
517
void print_sdf (std::ostream& os, int depth = 0 ) override {
508
- VTR_ASSERT (type_ == Type::RISING_EDGE);
518
+ VTR_ASSERT (type_ == Type::RISING_EDGE || type_ == Type::FALLING_EDGE );
509
519
510
520
os << indent (depth) << " (CELL\n " ;
511
521
os << indent (depth + 1 ) << " (CELLTYPE \" "
@@ -523,7 +533,7 @@ class LatchInst : public Instance {
523
533
delay_triple << " (" << delay_ps << " :" << delay_ps << " :" << delay_ps << " )" ;
524
534
525
535
os << indent (depth + 3 ) << " (IOPATH "
526
- << " (posedge clock) Q " << delay_triple.str () << " " << delay_triple.str () << " )\n " ;
536
+ << " (" << type_to_sdf_edge () << " clock) Q " << delay_triple.str () << " " << delay_triple.str () << " )\n " ;
527
537
os << indent (depth + 2 ) << " )\n " ;
528
538
os << indent (depth + 1 ) << " )\n " ;
529
539
}
@@ -535,13 +545,13 @@ class LatchInst : public Instance {
535
545
std::stringstream setup_triple;
536
546
double setup_ps = get_delay_ps (tsu_);
537
547
setup_triple << " (" << setup_ps << " :" << setup_ps << " :" << setup_ps << " )" ;
538
- os << indent (depth + 2 ) << " (SETUP D (posedge clock) " << setup_triple.str () << " )\n " ;
548
+ os << indent (depth + 2 ) << " (SETUP D (" << type_to_sdf_edge () << " clock) " << setup_triple.str () << " )\n " ;
539
549
}
540
550
if (!std::isnan (thld_)) {
541
551
std::stringstream hold_triple;
542
552
double hold_ps = get_delay_ps (thld_);
543
553
hold_triple << " (" << hold_ps << " :" << hold_ps << " :" << hold_ps << " )" ;
544
- os << indent (depth + 2 ) << " (HOLD D (posedge clock) " << hold_triple.str () << " )\n " ;
554
+ os << indent (depth + 2 ) << " (HOLD D (" << type_to_sdf_edge () << " clock) " << hold_triple.str () << " )\n " ;
545
555
}
546
556
}
547
557
os << indent (depth + 1 ) << " )\n " ;
@@ -1310,9 +1320,20 @@ class NetlistWriterVisitor : public NetlistVisitor {
1310
1320
std::string control_net = make_inst_wire (control_atom_net_id, find_tnode (atom, control_cluster_pin_idx), inst_name, PortType::CLOCK, 0 , 0 );
1311
1321
port_conns[" clock" ] = control_net;
1312
1322
1313
- // VPR currently doesn't store enough information to determine these attributes,
1314
- // for now assume reasonable defaults.
1315
- LatchInst::Type type = LatchInst::Type::RISING_EDGE;
1323
+ LatchInst::Type type;
1324
+
1325
+ auto atom_pb = g_vpr_ctx.atom ().lookup .pb_atom (atom);
1326
+ VTR_ASSERT (atom_pb != AtomBlockId::INVALID ());
1327
+
1328
+ const t_model* model = g_vpr_ctx.atom ().nlist .block_model (atom_pb);
1329
+
1330
+ if (model->inputs ->next ->trigg_edge == TriggeringEdge::FALLING_EDGE) {
1331
+ type = LatchInst::Type::FALLING_EDGE;
1332
+ } else {
1333
+ type = LatchInst::Type::RISING_EDGE;
1334
+ }
1335
+
1336
+ // VPR currently doesn't store enough information to determine this attribute
1316
1337
vtr::LogicValue init_value = vtr::LogicValue::FALSE ;
1317
1338
1318
1339
return std::make_shared<LatchInst>(inst_name, port_conns, type, init_value, tcq, tsu);
0 commit comments