1
1
/*
2
- * Copyright (c) 2000-2024 Stephen Williams ([email protected] )
2
+ * Copyright (c) 2000-2025 Stephen Williams ([email protected] )
3
3
* Copyright CERN 2013 / Stephen Williams ([email protected] )
4
4
*
5
5
* This source code is free software; you can redistribute it
@@ -942,7 +942,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
942
942
while (cscope && !cscope->find_genvar (loop_index)) {
943
943
if (cscope->symbol_exists (loop_index)) {
944
944
cerr << get_fileline () << " : error: "
945
- << " generate loop variable '" << loop_index
945
+ << " generate \" loop\" variable '" << loop_index
946
946
<< " ' is not a genvar in this scope." << endl;
947
947
des->errors += 1 ;
948
948
return false ;
@@ -967,8 +967,16 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
967
967
NetExpr*init_ex = elab_and_eval (des, container, loop_init, -1 , true );
968
968
NetEConst*init = dynamic_cast <NetEConst*> (init_ex);
969
969
if (init == 0 ) {
970
- cerr << get_fileline () << " : error: Cannot evaluate genvar"
971
- << " init expression: " << *loop_init << endl;
970
+ cerr << get_fileline () << " : error: "
971
+ " Cannot evaluate generate \" loop\" initialization "
972
+ " expression: " << *loop_init << endl;
973
+ des->errors += 1 ;
974
+ return false ;
975
+ }
976
+ if (! init->value ().is_defined ()) {
977
+ cerr << get_fileline () << " : error: "
978
+ << " Generate \" loop\" initialization expression cannot have "
979
+ " undefined bits. given (" << *loop_init << " )." << endl;
972
980
des->errors += 1 ;
973
981
return false ;
974
982
}
@@ -979,27 +987,43 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
979
987
980
988
if (debug_scopes)
981
989
cerr << get_fileline () << " : debug: genvar init = " << genvar << endl;
990
+
982
991
container->genvar_tmp = loop_index;
983
992
container->genvar_tmp_val = genvar;
984
993
NetExpr*test_ex = elab_and_eval (des, container, loop_test, -1 , true );
985
994
NetEConst*test = dynamic_cast <NetEConst*>(test_ex);
986
995
if (test == 0 ) {
987
- cerr << get_fileline () << " : error: Cannot evaluate genvar "
988
- << " conditional expression: " << *loop_test << endl;
996
+ cerr << get_fileline () << " : error: Cannot evaluate generate \" loop \" "
997
+ " conditional expression: " << *loop_test << endl;
989
998
des->errors += 1 ;
990
999
return false ;
991
1000
}
1001
+ if (! test->value ().is_defined ()) {
1002
+ cerr << get_fileline () << " : error: "
1003
+ " Generate \" loop\" conditional expression cannot have "
1004
+ " undefined bits. given (" << *loop_test << " )." << endl;
1005
+ des->errors += 1 ;
1006
+ return false ;
1007
+ }
1008
+ unsigned long loop_count = 1 ;
992
1009
while (test->value ().as_long ()) {
993
1010
994
1011
// The actual name of the scope includes the genvar so
995
1012
// that each instance has a unique name in the
996
1013
// container. The format of using [] is part of the
997
1014
// Verilog standard.
998
1015
hname_t use_name (scope_name, genvar);
1016
+ if (container->child (use_name)) {
1017
+ cerr << get_fileline () << " : error: "
1018
+ " Trying to create a duplicate generate scope named \" "
1019
+ << use_name << " \" ." << endl;
1020
+ des->errors += 1 ;
1021
+ return false ;
1022
+ }
999
1023
1000
1024
if (debug_scopes)
1001
1025
cerr << get_fileline () << " : debug: "
1002
- << " Create generated scope " << use_name << endl;
1026
+ " Create generated scope " << use_name << endl;
1003
1027
1004
1028
NetScope*scope = new NetScope (container, use_name,
1005
1029
NetScope::GENBLOCK);
@@ -1025,7 +1049,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
1025
1049
scope->set_parameter (loop_index, gp, *this );
1026
1050
if (debug_scopes)
1027
1051
cerr << get_fileline () << " : debug: "
1028
- << " Create implicit localparam "
1052
+ " Create implicit localparam "
1029
1053
<< loop_index << " = " << genvar_verinum << endl;
1030
1054
}
1031
1055
@@ -1035,23 +1059,58 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
1035
1059
NetExpr*step_ex = elab_and_eval (des, container, loop_step, -1 , true );
1036
1060
NetEConst*step = dynamic_cast <NetEConst*>(step_ex);
1037
1061
if (step == 0 ) {
1038
- cerr << get_fileline () << " : error: Cannot evaluate genvar "
1039
- << " step expression: " << *loop_step << endl;
1062
+ cerr << get_fileline () << " : error: Cannot evaluate generate "
1063
+ " \" loop \" increment expression: " << *loop_step << endl;
1040
1064
des->errors += 1 ;
1041
1065
return false ;
1042
1066
}
1043
1067
if (debug_scopes)
1044
1068
cerr << get_fileline () << " : debug: genvar step from "
1045
1069
<< genvar << " to " << step->value ().as_long () << endl;
1046
1070
1047
- genvar = step->value ().as_long ();
1071
+ if (! step->value ().is_defined ()) {
1072
+ cerr << get_fileline () << " : error: "
1073
+ " Generate \" loop\" increment expression cannot have "
1074
+ " undefined bits, given (" << *loop_step << " )." << endl;
1075
+ des->errors += 1 ;
1076
+ return false ;
1077
+ }
1078
+ long next_genvar;
1079
+ next_genvar = step->value ().as_long ();
1080
+ if (next_genvar == genvar) {
1081
+ cerr << get_fileline () << " : error: "
1082
+ << " The generate \" loop\" is not incrementing. The "
1083
+ " previous and next genvar values are ("
1084
+ << genvar << " )." << endl;
1085
+ des->errors += 1 ;
1086
+ return false ;
1087
+ }
1088
+ genvar = next_genvar;
1048
1089
check_for_valid_genvar_value_ (genvar);
1049
1090
container->genvar_tmp_val = genvar;
1050
1091
delete step;
1051
1092
delete test_ex;
1052
1093
test_ex = elab_and_eval (des, container, loop_test, -1 , true );
1053
1094
test = dynamic_cast <NetEConst*>(test_ex);
1054
1095
ivl_assert (*this , test);
1096
+ if (! test->value ().is_defined ()) {
1097
+ cerr << get_fileline () << " : error: "
1098
+ " The generate \" loop\" conditional expression cannot have "
1099
+ " undefined bits. given (" << *loop_test << " )." << endl;
1100
+ des->errors += 1 ;
1101
+ return false ;
1102
+ }
1103
+
1104
+ // If there are half a million iterations this is likely an infinite loop!
1105
+ if (loop_count > 500000 ) {
1106
+ cerr << get_fileline () << " : error: "
1107
+ << " Probable infinite loop detected in generate \" loop\" . "
1108
+ " It has run for " << loop_count
1109
+ << " iterations." << endl;
1110
+ des->errors += 1 ;
1111
+ return false ;
1112
+ }
1113
+ ++loop_count;
1055
1114
}
1056
1115
1057
1116
// Clear the genvar_tmp field in the scope to reflect that the
0 commit comments