@@ -431,6 +431,16 @@ class LatchInst : public Instance {
431431 return is;
432432 }
433433
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+
434444 public:
435445 LatchInst (std::string inst_name, // /<Name of this instance
436446 std::map<std::string, std::string> port_conns, // /<Instance's port-to-net connections
@@ -474,7 +484,7 @@ class LatchInst : public Instance {
474484
475485 void print_verilog (std::ostream& os, size_t & /* unconn_count*/ , int depth = 0 ) override {
476486 // Currently assume a standard DFF
477- VTR_ASSERT (type_ == Type::RISING_EDGE);
487+ VTR_ASSERT (type_ == Type::RISING_EDGE || type_ == Type::FALLING_EDGE );
478488
479489 os << indent (depth) << " DFF"
480490 << " #(\n " ;
@@ -505,7 +515,7 @@ class LatchInst : public Instance {
505515 }
506516
507517 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 );
509519
510520 os << indent (depth) << " (CELL\n " ;
511521 os << indent (depth + 1 ) << " (CELLTYPE \" "
@@ -523,7 +533,7 @@ class LatchInst : public Instance {
523533 delay_triple << " (" << delay_ps << " :" << delay_ps << " :" << delay_ps << " )" ;
524534
525535 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 " ;
527537 os << indent (depth + 2 ) << " )\n " ;
528538 os << indent (depth + 1 ) << " )\n " ;
529539 }
@@ -535,13 +545,13 @@ class LatchInst : public Instance {
535545 std::stringstream setup_triple;
536546 double setup_ps = get_delay_ps (tsu_);
537547 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 " ;
539549 }
540550 if (!std::isnan (thld_)) {
541551 std::stringstream hold_triple;
542552 double hold_ps = get_delay_ps (thld_);
543553 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 " ;
545555 }
546556 }
547557 os << indent (depth + 1 ) << " )\n " ;
@@ -1310,9 +1320,20 @@ class NetlistWriterVisitor : public NetlistVisitor {
13101320 std::string control_net = make_inst_wire (control_atom_net_id, find_tnode (atom, control_cluster_pin_idx), inst_name, PortType::CLOCK, 0 , 0 );
13111321 port_conns[" clock" ] = control_net;
13121322
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
13161337 vtr::LogicValue init_value = vtr::LogicValue::FALSE ;
13171338
13181339 return std::make_shared<LatchInst>(inst_name, port_conns, type, init_value, tcq, tsu);
0 commit comments