Skip to content

Commit fcc5c7b

Browse files
committed
$bits() must be given a valid data type
1 parent 9edaf7b commit fcc5c7b

14 files changed

Lines changed: 84 additions & 4 deletions

‎compiler.h‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,9 @@ extern bool gn_strict_parameter_declaration;
229229
*/
230230
extern bool gn_strict_net_var_declaration;
231231

232+
/* Allow $bits() to take a real argument. Not allowed by default. */
233+
extern bool gn_allow_real_arg_to_bits;
234+
232235
static inline bool gn_system_verilog(void)
233236
{
234237
if (generation_flag >= GN_VER2005_SV)

‎driver/iverilog.man.in‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.TH iverilog 1 "Jan 13th, 2026" "" "Version @VERSION@"
1+
.TH iverilog 1 "Sep 4th, 2026" "" "Version @VERSION@"
22
.SH NAME
33
iverilog - Icarus Verilog compiler
44

@@ -205,6 +205,12 @@ extensions. This includes the binary bitwise NAND and NOR operators
205205
and allowing the binary arithmetic modulus operator to operate on real
206206
operands.
207207
.TP 8
208+
.B -gallow-real-arg-to-bits\fI|\fP-gno-allow-real-arg-to-bits
209+
Starting in 1800-2012 the standard forbids passing a real value
210+
to \fB$bits()\fP. The compiler has traditionally reported the width
211+
of a real as 1. This is now flagged as an error by default. You can
212+
use this flag to enable the previous functionality.
213+
.TP 8
208214
.B -I\fIincludedir\fP
209215
Append directory \fIincludedir\fP to list of directories searched
210216
for Verilog include files. The \fB\-I\fP switch may be used many times

‎driver/main.c‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ const char*gen_io_range_error = "io-range-error";
138138
const char*gen_strict_ca_eval = "no-strict-ca-eval";
139139
const char*gen_strict_expr_width = "no-strict-expr-width";
140140
const char*gen_shared_loop_index = "shared-loop-index";
141+
const char*gen_allow_real_arg_to_bits = "no-allow-real-arg-to-bits";
141142
const char*gen_verilog_ams = "no-verilog-ams";
142143
const char*gen_strict_net_var_declaration = "strict-net-var-declaration";
143144
const char*gen_strict_parameter_declaration = "strict-parameter-declaration";
@@ -832,6 +833,12 @@ static int process_generation(const char*name)
832833
else if (strcmp(name,"no-shared-loop-index") == 0)
833834
gen_shared_loop_index = "no-shared-loop-index";
834835

836+
else if (strcmp(name,"allow-real-arg-to-bits") == 0)
837+
gen_allow_real_arg_to_bits = "allow-real-arg-to-bits";
838+
839+
else if (strcmp(name,"no-allow-real-arg-to-bits") == 0)
840+
gen_allow_real_arg_to_bits = "no-allow-real-arg-to-bits";
841+
835842
else if (strcmp(name,"verilog-ams") == 0)
836843
gen_verilog_ams = "verilog-ams";
837844

@@ -1445,6 +1452,7 @@ int main(int argc, char **argv)
14451452
fprintf(iconfig_file, "generation:%s\n", gen_strict_ca_eval);
14461453
fprintf(iconfig_file, "generation:%s\n", gen_strict_expr_width);
14471454
fprintf(iconfig_file, "generation:%s\n", gen_shared_loop_index);
1455+
fprintf(iconfig_file, "generation:%s\n", gen_allow_real_arg_to_bits);
14481456
fprintf(iconfig_file, "generation:%s\n", gen_verilog_ams);
14491457
fprintf(iconfig_file, "generation:%s\n", gen_strict_net_var_declaration);
14501458
fprintf(iconfig_file, "generation:%s\n", gen_strict_parameter_declaration);

‎elab_expr.cc‎

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2357,7 +2357,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope,
23572357
if (!data_type->packed()) {
23582358
use_width = 0;
23592359
cerr << get_fileline() << ": error: "
2360-
<< "Invalid data type for $bits()."
2360+
<< "Invalid data type for " << name << "()."
23612361
<< endl;
23622362
des->errors++;
23632363
} else {
@@ -2369,6 +2369,31 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope,
23692369
}
23702370

23712371
} else {
2372+
switch(expr->expr_type()) {
2373+
case IVL_VT_BOOL:
2374+
case IVL_VT_LOGIC: // This also covers IVL_VT_VECTOR
2375+
case IVL_VT_STRING:
2376+
break;
2377+
case IVL_VT_NO_TYPE:
2378+
cerr << get_fileline() << ": error: Argument with no known data type '"
2379+
<< *expr << "' passed to " << name << "()." << endl;
2380+
des->errors++;
2381+
break;
2382+
case IVL_VT_REAL:
2383+
// Traditionally iverilog returned 1 for the width of a real.
2384+
// Since 1800-2012 this is now forbidden by the standard.
2385+
// To support older code skip the error when requested.
2386+
if (gn_allow_real_arg_to_bits) break;
2387+
cerr << get_fileline() << ": error: Real argument '"
2388+
<< *expr << "' passed to " << name << "()." << endl;
2389+
des->errors++;
2390+
break;
2391+
default:
2392+
cerr << get_fileline() << ": sorry: Argument '" << *expr << "' of type '"
2393+
<< expr->expr_type() << "' passed to " << name << "(). is not "
2394+
"currently supported" << endl;
2395+
des->errors++;
2396+
}
23722397
use_width = expr->expr_width();
23732398
if (debug_elaborate) {
23742399
cerr << get_fileline() << ": PECallFunction::elaborate_sfunc_: "

‎ivtest/gold/br_gh1112a.gold‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
./ivltests/br_gh1112a.v:3: error: Argument with no known data type 'value' passed to $bits().
2+
1 error(s) during elaboration.

‎ivtest/gold/br_gh1112b.gold‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
./ivltests/br_gh1112b.v:3: error: Argument with no known data type 'top' passed to $bits().
2+
1 error(s) during elaboration.

‎ivtest/gold/br_gh1112c.gold‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
./ivltests/br_gh1112c.v:3: error: Real argument '1.00000' passed to $bits().
2+
1 error(s) during elaboration.
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
ivltests/early_sig_elab3.v:8: error: Circular dependency detected in declaration of 'a'.
2-
1 error(s) during elaboration.
2+
ivltests/early_sig_elab3.v:9: error: Argument with no known data type 'test.a' passed to $bits().
3+
2 error(s) during elaboration.

‎ivtest/ivltests/br_gh1112a.v‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module top;
2+
// An undefined value cannot be passed to $bits().
3+
localparam width = $bits(value);
4+
initial $display("FAILED: elaborated a width of %0d", width);
5+
endmodule

‎ivtest/ivltests/br_gh1112b.v‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module top;
2+
// A scope cannot be passed to $bits().
3+
localparam width = $bits(top);
4+
initial $display("FAILED: elaborated a width of %0d", width);
5+
endmodule

0 commit comments

Comments
 (0)