@@ -316,10 +316,10 @@ struct AST_INTERNAL::ProcessGenerator
316
316
// Buffer for generating the init action
317
317
RTLIL::SigSpec init_lvalue, init_rvalue;
318
318
319
- // The most recently assigned $print cell \PRIORITY.
320
- int last_print_priority ;
319
+ // The most recently assigned $print or $check cell \PRIORITY.
320
+ int last_effect_priority ;
321
321
322
- ProcessGenerator (AstNode *always, RTLIL::SigSpec initSyncSignalsArg = RTLIL::SigSpec()) : always(always), initSyncSignals(initSyncSignalsArg), last_print_priority (0 )
322
+ ProcessGenerator (AstNode *always, RTLIL::SigSpec initSyncSignalsArg = RTLIL::SigSpec()) : always(always), initSyncSignals(initSyncSignalsArg), last_effect_priority (0 )
323
323
{
324
324
// rewrite lookahead references
325
325
LookaheadRewriter la_rewriter (always);
@@ -703,8 +703,10 @@ struct AST_INTERNAL::ProcessGenerator
703
703
std::stringstream sstr;
704
704
sstr << ast->str << " $" << ast->filename << " :" << ast->location .first_line << " $" << (autoidx++);
705
705
706
- RTLIL::Cell *cell = current_module->addCell (sstr.str (), ID ($print));
707
- set_src_attr (cell, ast);
706
+ Wire *en = current_module->addWire (sstr.str () + " _EN" , 1 );
707
+ set_src_attr (en, ast);
708
+ proc->root_case .actions .push_back (SigSig (en, false ));
709
+ current_case->actions .push_back (SigSig (en, true ));
708
710
709
711
RTLIL::SigSpec triggers;
710
712
RTLIL::Const polarity;
@@ -717,18 +719,15 @@ struct AST_INTERNAL::ProcessGenerator
717
719
polarity.bits .push_back (RTLIL::S0);
718
720
}
719
721
}
720
- cell->parameters [ID::TRG_WIDTH] = triggers.size ();
721
- cell->parameters [ID::TRG_ENABLE] = !triggers.empty ();
722
- cell->parameters [ID::TRG_POLARITY] = polarity;
723
- cell->parameters [ID::PRIORITY] = --last_print_priority;
724
- cell->setPort (ID::TRG, triggers);
725
722
726
- Wire *wire = current_module->addWire (sstr.str () + " _EN" , 1 );
727
- set_src_attr (wire, ast);
728
- cell->setPort (ID::EN, wire);
729
-
730
- proc->root_case .actions .push_back (SigSig (wire, false ));
731
- current_case->actions .push_back (SigSig (wire, true ));
723
+ RTLIL::Cell *cell = current_module->addCell (sstr.str (), ID ($print));
724
+ set_src_attr (cell, ast);
725
+ cell->setParam (ID::TRG_WIDTH, triggers.size ());
726
+ cell->setParam (ID::TRG_ENABLE, !triggers.empty ());
727
+ cell->setParam (ID::TRG_POLARITY, polarity);
728
+ cell->setParam (ID::PRIORITY, --last_effect_priority);
729
+ cell->setPort (ID::TRG, triggers);
730
+ cell->setPort (ID::EN, en);
732
731
733
732
int default_base = 10 ;
734
733
if (ast->str .back () == ' b' )
@@ -776,6 +775,74 @@ struct AST_INTERNAL::ProcessGenerator
776
775
}
777
776
break ;
778
777
778
+ // generate $check cells
779
+ case AST_ASSERT:
780
+ case AST_ASSUME:
781
+ case AST_LIVE:
782
+ case AST_FAIR:
783
+ case AST_COVER:
784
+ {
785
+ std::string flavor, desc;
786
+ if (ast->type == AST_ASSERT) { flavor = " assert" ; desc = " assert ()" ; }
787
+ if (ast->type == AST_ASSUME) { flavor = " assume" ; desc = " assume ()" ; }
788
+ if (ast->type == AST_LIVE) { flavor = " live" ; desc = " assert (eventually)" ; }
789
+ if (ast->type == AST_FAIR) { flavor = " fair" ; desc = " assume (eventually)" ; }
790
+ if (ast->type == AST_COVER) { flavor = " cover" ; desc = " cover ()" ; }
791
+
792
+ std::stringstream sstr;
793
+ sstr << " $" << flavor << ast->str << " $" << ast->filename << " :" << ast->location .first_line << " $" << (autoidx++);
794
+
795
+ RTLIL::SigSpec check = ast->children [0 ]->genWidthRTLIL (-1 , false , &subst_rvalue_map.stdmap ());
796
+ if (GetSize (check) != 1 )
797
+ check = current_module->ReduceBool (NEW_ID, check);
798
+
799
+ RTLIL::SigSpec en;
800
+ RTLIL::SigSpec triggers;
801
+ RTLIL::Const polarity;
802
+ if (always->type == AST_ALWAYS) {
803
+ Wire *enWire = current_module->addWire (sstr.str () + " _EN" , 1 );
804
+ set_src_attr (enWire, ast);
805
+ en = enWire;
806
+
807
+ proc->root_case .actions .push_back (SigSig (enWire, false ));
808
+ current_case->actions .push_back (SigSig (enWire, true ));
809
+
810
+ for (auto sync : proc->syncs ) {
811
+ if (sync ->type == RTLIL::STp) {
812
+ triggers.append (sync ->signal );
813
+ polarity.bits .push_back (RTLIL::S1);
814
+ } else if (sync ->type == RTLIL::STn) {
815
+ triggers.append (sync ->signal );
816
+ polarity.bits .push_back (RTLIL::S0);
817
+ }
818
+ }
819
+ } else {
820
+ en = current_module->Initstate (NEW_ID);
821
+ }
822
+
823
+ RTLIL::IdString cellname = ast->str .empty () ? sstr.str () : ast->str ;
824
+ RTLIL::Cell *cell = current_module->addCell (cellname, ID ($check));
825
+ set_src_attr (cell, ast);
826
+ for (auto &attr : ast->attributes ) {
827
+ if (attr.second ->type != AST_CONSTANT)
828
+ log_file_error (ast->filename , ast->location .first_line , " Attribute `%s' with non-constant value!\n " , attr.first .c_str ());
829
+ cell->attributes [attr.first ] = attr.second ->asAttrConst ();
830
+ }
831
+ cell->setParam (ID (FLAVOR), flavor);
832
+ cell->setParam (ID::TRG_WIDTH, triggers.size ());
833
+ cell->setParam (ID::TRG_ENABLE, !triggers.empty ());
834
+ cell->setParam (ID::TRG_POLARITY, polarity);
835
+ cell->setParam (ID::PRIORITY, --last_effect_priority);
836
+ cell->setPort (ID::TRG, triggers);
837
+ cell->setPort (ID::EN, en);
838
+ cell->setPort (ID::A, check);
839
+
840
+ Fmt fmt = {};
841
+ fmt.append_string (stringf (" %s failed at %s:%d" , desc.c_str (), RTLIL::encode_filename (ast->filename ).c_str (), ast->location .first_line ));
842
+ fmt.emit_rtlil (cell);
843
+ break ;
844
+ }
845
+
779
846
case AST_NONE:
780
847
case AST_FOR:
781
848
break ;
@@ -1945,48 +2012,50 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
1945
2012
}
1946
2013
break ;
1947
2014
1948
- // generate $assert cells
2015
+ // generate $check cells
1949
2016
case AST_ASSERT:
1950
2017
case AST_ASSUME:
1951
2018
case AST_LIVE:
1952
2019
case AST_FAIR:
1953
2020
case AST_COVER:
1954
2021
{
1955
- IdString celltype;
1956
- if (type == AST_ASSERT) celltype = ID ($assert);
1957
- if (type == AST_ASSUME) celltype = ID ($assume);
1958
- if (type == AST_LIVE) celltype = ID ($live);
1959
- if (type == AST_FAIR) celltype = ID ($fair);
1960
- if (type == AST_COVER) celltype = ID ($cover);
1961
-
1962
- log_assert (children.size () == 2 );
2022
+ std::string flavor, desc;
2023
+ if (type == AST_ASSERT) { flavor = " assert" ; desc = " assert property ()" ; }
2024
+ if (type == AST_ASSUME) { flavor = " assume" ; desc = " assume property ()" ; }
2025
+ if (type == AST_LIVE) { flavor = " live" ; desc = " assert property (eventually)" ; }
2026
+ if (type == AST_FAIR) { flavor = " fair" ; desc = " assume property (eventually)" ; }
2027
+ if (type == AST_COVER) { flavor = " cover" ; desc = " cover property ()" ; }
1963
2028
1964
2029
RTLIL::SigSpec check = children[0 ]->genRTLIL ();
1965
2030
if (GetSize (check) != 1 )
1966
2031
check = current_module->ReduceBool (NEW_ID, check);
1967
2032
1968
- RTLIL::SigSpec en = children[1 ]->genRTLIL ();
1969
- if (GetSize (en) != 1 )
1970
- en = current_module->ReduceBool (NEW_ID, en);
1971
-
1972
2033
IdString cellname;
1973
2034
if (str.empty ())
1974
- cellname = stringf (" %s$%s:%d$%d" , celltype .c_str (), RTLIL::encode_filename (filename).c_str (), location.first_line , autoidx++);
2035
+ cellname = stringf (" $ %s$%s:%d$%d" , flavor .c_str (), RTLIL::encode_filename (filename).c_str (), location.first_line , autoidx++);
1975
2036
else
1976
2037
cellname = str;
1977
-
1978
2038
check_unique_id (current_module, cellname, this , " procedural assertion" );
1979
- RTLIL::Cell *cell = current_module->addCell (cellname, celltype);
1980
- set_src_attr (cell, this );
1981
2039
2040
+ RTLIL::Cell *cell = current_module->addCell (cellname, ID ($check));
2041
+ set_src_attr (cell, this );
1982
2042
for (auto &attr : attributes) {
1983
2043
if (attr.second ->type != AST_CONSTANT)
1984
2044
input_error (" Attribute `%s' with non-constant value!\n " , attr.first .c_str ());
1985
2045
cell->attributes [attr.first ] = attr.second ->asAttrConst ();
1986
2046
}
1987
-
2047
+ cell->setParam (ID (FLAVOR), flavor);
2048
+ cell->parameters [ID::TRG_WIDTH] = 0 ;
2049
+ cell->parameters [ID::TRG_ENABLE] = 0 ;
2050
+ cell->parameters [ID::TRG_POLARITY] = 0 ;
2051
+ cell->parameters [ID::PRIORITY] = 0 ;
2052
+ cell->setPort (ID::TRG, RTLIL::SigSpec ());
2053
+ cell->setPort (ID::EN, RTLIL::S1);
1988
2054
cell->setPort (ID::A, check);
1989
- cell->setPort (ID::EN, en);
2055
+
2056
+ Fmt fmt = {};
2057
+ fmt.append_string (stringf (" %s failed at %s:%d" , desc.c_str (), RTLIL::encode_filename (filename).c_str (), location.first_line ));
2058
+ fmt.emit_rtlil (cell);
1990
2059
}
1991
2060
break ;
1992
2061
0 commit comments